Update/Put error save in Express and Mongoose - javascript

I am beginner in Express. I have the following code in my router/controller for update a model. In one hand I don't want to modify the date of "create_date" parameter, and on the second hand this code returns me a error.
updateFood = function(req, res){
Food.findById(req.params.id, function(err, food){
food.food_name = req.body.food_name;
food.description = req.body.description;
food.image = req.body.image;
food.create_date = Date.now();
food.category = req.body.category;
Food.save(function(err){
if (!err){
console.log("updated!");
} else {
console.log(err);
}
});
res.send(food);
});
};
Here is my schema:
var food = new Schema({
food_name: {type: String, unique: true},
description: String,
image: String,
create_date: {type: Date, default: Date.now()},
category: {
type: String,
cats: ['Meat', 'Fish', 'Vegetables']
}
});
module.exports = mongoose.model('Food', food);
When I try to update a food with Postman with PUT. The console returns me the following response:
Food.save(function(err){
^
TypeError: Object function model(doc, fields, skipId) {
if (!(this instanceof model))
return new model(doc, fields, skipId);
Model.call(this, doc, fields, skipId);
} has no method 'save'
What can I do? Anyone knows where is my mistake? Thanks.

I believe you meant food.save(..); instead of Food.save(..);, but if all you're doing is updating the model, you could use findByIdAndUpdate() instead.

Related

Cannot read the property of id undefined

I'm making a website where you can share campground photos. And when someone makes a comments I want only comment's owner to see delete and edit options.
I've made an model for comment and made an author object that includes comment's owner's id and username. But when I try to get the owner's ID from that author object it returns undefined also if I try to get data by find method and write Comment.author.id it returns syntax error and says Unexpected token "."
That's my comment model.
var commentSchema = new mongoose.Schema({
text: String,
author:{
username: String,
id: String,
}
});
That's the campground route
Campground.findById(req.params.id).populate("comments").exec(function(err, foundCampground){
if(err){
console.log(err);
}else{
//render show template with that campground
console.log(foundCampground.comments);
User.findById(req.user._id, (err, user)=>{
if(err){
console.log(err);
}else{
console.log(foundCampground.comments._id);
Comments.find({Comments.author.id: foundCampground.comments._id}, function(err, comment){
var authID = foundCampground.author.id;
var userID = user._id;
var commentID = comment.author.id;
console.log("Comment Id " + commentID);
console.log("UserID "+userID);
res.render("campgrounds/show",{campground: foundCampground, authID: authID, userID: userID});
});
}
});
}
});
Same thing worked for the campground model
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}],
author: {
id: String,
user: String,
}
});
I expect to get the user id from comment.author.id but I get undefined.
You may need to replace Comments.find({Comments.author.id: foundCampground.comments._id} with Comments.find({"author.id": foundCampground.comments._id}.

Update Array attribute using Mongoose

I am working on a MEAN stack application in which i defined a model using following schema:
var mappingSchema = new mongoose.Schema({
MainName: String,
Addr: String,
Mapping1: [Schema1],
Mappings2: [Schema2]
},
{collection : 'Mappings'}
);
I am displaying all this data on UI and Mapping1 & Mapping2 are displayed in the 2 tables where I can edit the values. What I am trying to do is once I update the values in table I should update them in database. I wrote put() api where I am getting these two updated mappings in the form of object but not able to update it in database. I tried using findAndModify() & findOneAndUpdate() but failed.
Here are the Schema1 & Schema2:
const Schema1 = new mongoose.Schema({
Name: String,
Variable: String
});
const Schema2 = new mongoose.Schema({
SName: String,
Provider: String
});
and my put api:
.put(function(req, res){
var query = {MainName: req.params.mainname};
var mapp = {Mapping1: req.params.mapping1, Mapping2: req.params.mapping2};
Mappings.findOneAndUpdate(
query,
{$set:mapp},
{},
function(err, object) {
if (err){
console.warn(err.message); // returns error if no matching object found
}else{
console.log(object);
}
});
});
Please suggest the best to way update those two arrays.
UPDATE :
I tried this
var mapp = {'Mapping2': req.params.mapping2};
Mappings.update( query ,
mapp ,
{ },
function (err, object) {
if (err || !object) {
console.log(err);
res.json({
status: 400,
message: "Unable to update" + err
});
} else {
return res.json(object);
}
});
what I got is
My array with size 3 is saved as String in Mapping2 array.
Please help. Stuck badly. :(
From Mongoose's documentation I believe there's no need to use $set. Just pass an object with the properties to update :
Mappings.findOneAndUpdate(
query,
mapp, // Object containing the keys to update
function(err, object) {...}
);

JSON object architecture looks different when I pass it to the client side

Here is my Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var messageSchema = new Schema({
requestNumber: String,
requestedDateTime: String,
reasons: String,
state: String,
hospital: String,
phone: String,
status: {type: String, default: 'Pending'},
latestUpdate: Date,
createdAt: {type: Date, default: Date.now}
});
module.exports = mongoose.model('Requests', messageSchema);
Below I am returning the collection with three components in it
ipcMain.on('load-requests', function(event) {
hosSchemaModel.find(function(err, hosSchema) {
if (err) {
console.log('inside error') // return res.send(err);
} else {
event.sender.send('requests-results', hosSchema) // this line of code passes hosSchema to the client side
console.log(hosSchema[0].state) //prints the state attribute of the first component in the collection without any errors.
}
});
});
When I try to console.log(hosSchema) in the server, I get the following printed to the terminal:
and I could successfully access the properties such as status of the first component in the collection by referring to its index hosSchema[0].status.
Below I am trying to print hosSchema to the console (in the front-end)
ipcRenderer.on('requests-results', (event, hosSchema) => {
console.log(hosSchema)
})
I get the result different from what they were looking in the terminal. below is the picture
and hosSchema[0].status returns undefined.
My questions are:
1) why hosSchema[0].status doesn't work in the front-end?
2) what is the correct way to access the properties in the client-side?
All you have to do in the front end is to use hosSchema[0]._doc.status instead of hosSchema[0].status

Removing element from nested array in Mongoose

I'm working on an upvoting/downvoting application using MongoDB and Node.JS
I have created two interlinked schemas:
var mongoose = require('mongoose');
var Voters = require('./voters');
var PostSchema = new mongoose.Schema({
title: String,
link: String,
upvotes: {type: Number, default: 0},
voters: [Voters.schema],
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
mongoose.model('Post', PostSchema);
and for voters:
var mongoose = require('mongoose');
var votersSchema = new mongoose.Schema({
voter_id: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
votetype: Number
});
module.exports = mongoose.model('Voters', votersSchema);
For including users in the voters array, I'm using this code:
var voterModel = new Voters();
voterModel.voter_id = req.payload._id;
voterModel.votetype = 1;
foundPost.voters.push(voterModel);
foundPost.save();
Which works just fine. For removing users I tried several methods, but none seem to work. The current one is $pull:
foundPost.update({'voters.voter_id': req.payload._id}, {$pull: {'voters': {'voter_id': req.payload._id, 'votetype': 1}}}, function(err){
if (err) { console.log(err); }
});
The update action works in the mongo shell, but not from within node. I also tried foundPost.voters.remove, but the result was the same. Also tried Voters.findOne, but the query always returns null.
Any help would be appreciated.
Use the id method first to find the voter then remove it and last save document to apply changes:
var voter = foundPost.voters.id(req.payload._id).remove();
foundPost.save(function (err) {
if (err) return handleError(err);
console.log('the voter was removed')
});

Auto incrementing sequence field error - MongoDB, Mongoose

I followed this SO question to generate an auto-increment sequence field in mongoose.
But on implementing & running the code I get the following error:
TypeError: Cannot read property 'seq' of null
Heres my code below:
Counter.js File
// app/models/counter.js
// load the things we need
var mongoose = require('mongoose');
// define the schema for our user model
var counterSchema = mongoose.Schema({
_id: {type: String, required: true},
seq: {type: Number, default: 0}
});
// methods ======================
// create the model for users and expose it to our app
module.exports = mongoose.model('Counter', counterSchema);
SupportTicket.js File
var Counter = require('../models/counter');
var ticketSchema = mongoose.Schema({
issue: String,
ticketNo: Number,
dateCreated : { type: Date, default: Date.now }
});
ticketSchema.pre('save', function(next) {
var doc = this;
Counter.findByIdAndUpdate({_id: 'entityId'}, {$inc: { seq: 1}}, function(error, counter) {
if(error)
return next(error);
doc.ticketNo = counter.seq;
next();
});
});
I can't figure out why am I getting the "Cannot read property 'seq' of null"
Any suggestions?
counter.findByIdAndUpdate({_id: 'url_count'},
{$inc: {seq: 1} },
{upsert: true , new: true},
function(error, counter)
Add This line.This will work fine.
{upsert: true , new: true}

Categories

Resources