Chenya Zhang Chenya Zhang - 3 months ago 43
Javascript Question

".findOneAndUpdate()" not updating database properly (Mongodb & Node.js)

I try to use

.findOneAndUpdate()
to update my database.

No error message, but this part of the database is not updated with new data. The embedded document
competitorAnalysisTextData
is still empty.

// on routes that end in /users/competitorAnalysisTextData
// ----------------------------------------------------
router.route('/users/competitorAnalysisTextData/:userName')

// update the user info (accessed at PUT http://localhost:8080/api/users/competitorAnalysisTextData)
.post(function(req, res) {

console.log('1');

// Just give instruction to mongodb to find document, change it;
// then finally after mongodb is done, return the result/error as callback.
User.findOneAndUpdate(
{ userName : req.params.userName},
{
$set:
{ "competitorAnalysis.firstObservation" : req.body.firstObservation,
"competitorAnalysis.secondObservation" : req.body.secondObservation,
"competitorAnalysis.thirdObservation" : req.body.thirdObservation,
"competitorAnalysis.brandName" : req.body.brandName,
"competitorAnalysis.productCategory" : req.body.productCategory
}
},
{ upsert: true },
function(err, user) {
// after mongodb is done updating, you are receiving the updated file as callback
console.log('2');
// now you can send the error or updated file to client
if (err)
return res.send(err);

return res.json({ message: 'User updated!' });
});

})


Update

This is my "User" Schema part:

// grab the things we need
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// Require the crypto module for password hash
'use strict';
var crypto = require('crypto');

// create competitorAnalysisSchema
var CompetitorAnalysis = new Schema({
firstObservation: { type: String },
secondObservation: { type: String },
thirdObservation: { type: String },
brandName: { type: String },
productCategory: { type: String }
});
// create competitorAnalysisPhotoSchema
var CompetitorAnalysisPhoto = new Schema({
photo1: {type: String},
photo2: {type: String},
photo3: {type: String},
photo4: {type: String}
});
// create UserSchema
var UserSchema = new Schema({
userName: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
currentDemo: { type: String },
nextDemo: { type: String },
startTime: { type: String },
startLocation: { type: String },
arriveTime: { type: String },
arriveLocation: { type: String },
leaveTime: { type: String },
leaveLocation: { type: String },
competitorAnalysis: [CompetitorAnalysis],
competitorAnalysisPhoto: [CompetitorAnalysisPhoto],
created_at: Date,
updated_at: Date
});

// the schema is useless so far
// we need to create a model using it
var User = mongoose.model('User', UserSchema);

// make this available to our users in our Node applications
module.exports = User;

Answer

in javascript if you wish to update an object inside an array, you need to pick the index

var arr = [{name: "person1"},{name:"person2"}]
arr[0].name = "myname"
arr[1].name = "myFriend"

So it's the same in mongodb, check this link for detail example, or you can manually input the index, for quick hack.

User.findOneAndUpdate(
  { userName : req.params.userName},
  {
    $set:
    {   "competitorAnalysis.0.firstObservation" : req.body.firstObservation,
        "competitorAnalysis.0.secondObservation" : req.body.secondObservation,
        "competitorAnalysis.0.thirdObservation" : req.body.thirdObservation,
        "competitorAnalysis.0.brandName" : req.body.brandName,
        "competitorAnalysis.0.productCategory" : req.body.productCategory
    }
  },
  { upsert: true },
  function(err, user) {
    // after mongodb is done updating, you are receiving the updated file as callback
    console.log('2');
    // now you can send the error or updated file to client
    if (err)
        return res.send(err);

    return res.json({ message: 'User updated!' });
  });

})

You should use the code above to update nested-array not to add to empty-array. In javascript, if an array is still empty, we use .push() to add, while in mongodb the command is $push

var arr = []
arr.push({name:"person1"})