Nodejs Duplicate Fields - node.js

I'm using a POST route to post data on a user's progress. I'm looking for a way to check if theres duplicate fields when posting, so I don't post multiple results
My route:
api.post('/progress', (req, res) => {
let progress = new Progress();
progress.user_id = req.body.user_id;
progress.level = req.body.level;
progress.save(function (err) {
if (err) {
res.send(err);
}
res.json({
message: 'progress saved!'
});
});
});
My Model
import mongoose from 'mongoose';
let Schema = mongoose.Schema;
let progressSchema = new Schema({
user_id: String,
level: String,
});
var levels = mongoose.model('Progress', progressSchema);
module.exports = mongoose.model('Progress', progressSchema);

Are you using MongoDB? If so, you can use mongoose module and add
unique: true,
to the field's attributes in your Progress schema. Check out the docs. Hope this helps.

Related

Mongoose append additional properties to the results based on conditional checks

i want to add additional properties to the result document of a mongoose query. i have a Post Model, inside the post model i have added favourites which contains reference to the users who favourited the post, i want to get whether the user has favourited the post and the total number of favourites the post has
Post Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mongoosePaginate = require('mongoose-paginate-v2');
var aggregatePaginate = require('mongoose-aggregate-paginate-v2');
const postSchema = Schema({
title: String,
favourites: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}],
description: String
});
var Post = mongoose.model('Post', postSchema.plugin(mongoosePaginate));
Post.prototype.hasLiked = function (uid) {
return this.favourites.indexOf(uid) > -1
}
Post.prototype.totalLikes = function () {
return this.favourites.length;
}
module.exports = Post;
Controller
Post.paginate(query,
options,
function (err, result) {
if (err) {
console.log(err)
res.json({
error: err,
status: 501,
message: "Unable to get data"
});
} else {
let isFavourite = result.hasLiked(res.locals.user.uid)
let favouriteLength = result.totalLikes()
console.log(isFavourite)
console.log(favouriteLength)
res.json({
status: 200,
data: result
});
}
}
);
});
Im facing the following error while running the above code
TypeError: result.hasLiked is not a function
Is this an efficient solution, if not please suggest any alternate solution for this scenario.
Post.paginate doesn't return a promise fulfilled with an instance of Post.
Following the documentation ( https://www.npmjs.com/package/mongoose-paginate-v2 ), you will receive your post in result.docs. Loop on it and you can use your getters.

How can I sort and limit with Mongoose

I made an review app with Express and Mongoose. I have an review model like below:
var mongoose = require('mongoose');
var ReviewSchema = mongoose.Schema({
title: String,
description: String,
rating: Number
}, {
timestamps: true
}
);
module.exports = mongoose.model('Review', ReviewSchema);
In my controller I just get all reviews list as below. But now I want to get a list with 10 recently reviews & sort by (orderby timestamps). How can I do it with mongoose? Please help me! I am a newbie with NodeJS and Mongodb.
exports.findAll = function(req, res) {
console.log("Fetching Review...")
// Retrieve and return all reviews from the database.
Review.find(function(err, reviews){
if(err) {
console.log(err);
res.status(500).send({message: "Some error occurred while retrieving Review."});
} else {
res.send(reviews);
}
});
};
Thanks you so much
This should work for you:
Review.find()
.sort({_id: -1})
.limit(10)
.then(reviews => {
console.log(reviews)
});
you can try like this :
Review.find({}, function(err,reviews){}).sort({_id: -1}).limit(10);

Need a better way to fill values from req.body into a model

I am creating a webapp using the following stack:
Node
Express
MongoDB
Mongoose
I have structured the app into a MVC structure. In the app I need to get create (post) and update (put) data values which I get from res.body and copy them to Mongoose Model. For example I am doing the following:
Mongoose Model:
let mongoose = require('mongoose');
let customerPaymentType = mongoose.Schema({
type: { type: String, required: true, unique: true}
},
{
timestamps: true
}
);
module.exports = mongoose.model('CustomerPaymentType', customerPaymentType);
Controller (Only a part):
let mongoose = require('mongoose');
let CustomerPaymentType = mongoose.model('CustomerPaymentType');
class CustomerPaymentTypeController {
constructor(){}
create(req, res){
let customerPaymentType = new CustomerPaymentType();
this._setCustomerPaymentType(req.body, customerPaymentType);
customerPaymentType.save(error=>{
if (error) res.send(error);
res.json({
message: 'Customer payment type successfully created',
customerPaymentType:{_id: customerPaymentType._id}
});
});
}
//private methods
_setCustomerPaymentType(rawCustomerPaymentType, customerPaymentType){
if (typeof rawCustomerPaymentType.type !== 'undefined') customerPaymentType.type = rawCustomerPaymentType.type.trim();
}
}
module.exports = CustomerPaymentTypeController;
In this model there is only one field, thus populating the model with the data from the req.body in the controller file is easy. But I have other models with more than 30 fields, and it is taking long time to populate them. Is there any easier way to deal with repopulating a model, similar to one present in Ruby on Rails?

Mongoose: Is it possible to set strict:false after defining the schema, like through a middleware or a plugin?

When you define a schema in Mongoose you have an option to set {strict:false}
Is there an option to have that set after you've defined the schema? Like through a mongoose middleware or a mongoose plugin?
I want to create a plugin which will need to store some additional data into the database, which I wouldn't be able to unless the plugin user has either set {strict:false} or added the fields that I would want to store data in their schema themselves, both of which are unlikely. So I was wondering if there's a way for me to make that happen from my plugin code itself?
Mongoose is an ODM, and the {strict: true} option in this regard only applies to queries you run through Mongoose, it's not enforced in the mongoDB side, your documents remain schemaless.
But you don't have to use mongoose to make all of your queries, you can use the native mongoDB driver underneath in order to bypass all of that. Mongoose even gives you a shortcut to do so in the form of Model.collection. Here's an example:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PersonSchema = new Schema({
name: String
}, {
strict: true
});
var Person = mongoose.model('Person', PersonSchema);
mongoose.connect('mongodb://localhost/test', function(err) {
if (err) {
throw err;
}
Person.collection.insert({
name: 'Bill',
extraProp: 'Hello World'
}, function(err, result) {
if (err) {
throw err;
}
console.log(result);
});
console.log('Connected');
});
Edit:
You can disable strict for specific model paths. I think this is more what you're looking for.
PersonSchema.pre('save', function(next) {
this.set('extraProp', 'hello', {
strict: false
});
next();
});
Just an FYI, what I ended up doing was creating a sub-schema, then disabling strict in there..
I was doing this for meta data, which is unstructured, so heres my example:
module.exports = Mongoose => {
const Schema = Mongoose.Schema
const metaSchema = new Schema({},{ strict: false })
const modelSchema = new Schema({
title: Schema.Types.String,
metaData: metaSchema
})
modelSchema.statics.createMeta = function( title, meta, cb ) {
return new this({
title: title,
metaData: meta
}).save()
}
return Mongoose.model( 'Foobar', modelSchema )
}
Then to use it:
Foobar.createMeta( 'blah blah', {
foo: 'AA',
bar: 'BB'
} )
.then( data => console.log( '# RESULT:', data ) )
.catch( err => console.error( 'ERROR:',err ) )
Which seems to work fine :)

Mongoose save callback doesn't fire

I'm new to mongoose and I'm having a hard time finding the issue within my code. I'm building a REST server using Sails.js and Mongoose. I have a node module (e.g. "sails-mongoose") for exporting mongoose, where I also connect to my database:
var mongoose = require('mongoose');
mongoose.connect('mongodb://#localhost:27017/fooria');
module.exports = mongoose;
And in my model.js:
var adapter = require('sails-mongoose');
var schema = new adapter.Schema({
firstname: {
type: String,
required: true,
trim: true
}
});
module.exports = {
schema: schema,
model: adapter.model('Collection', schema)
}
In my controller's create method I have:
create: function(req, res, next) {
var userData = {firstname: 'Test'};
var users = new Users.model(userData);
users.save(function(err, data){
if (err) return res.json(err, 400);
res.json(data, 201);
});
}
When running create method, the entry is saved to the Mongodb collection but the callback is never reached. Can someone please help me on this track, as I found similar questions but none helped me though. Thanks!
I suppose your are using Express. According Express docs you are calling res.json using incorrect parameters (wrong order).
Correct format:
res.json(code, data)
Example:
res.json(500, { error: 'message' })

Resources