MongoDB and Mongoose - Perform Classic Updates by Running Find, Edit, then Save

MongoDB and Mongoose - Perform Classic Updates by Running Find, Edit, then Save
0

#1

Getting error message:

Find-edit-update an item should succeed

My code so far

var findEditThenSave = function(personId, done) {
  var foodToAdd = 'hamburger';
  Person.findById(personId, function(err, data) {
    this.favoriteFoods.push(foodToAdd).save();
    if (err) {
      return done(err);
    }
    else {
      done(null, data);
    }
  });
};

Any help would be appreciated, I don’t see it… :frowning:

Link to the challenge:
https://learn.freecodecamp.org/apis-and-microservices/mongodb-and-mongoose/perform-classic-updates-by-running-find-edit-then-save


#2

I think it’s because you are calling this.favoriteFoods.

this has no meaning inside the callback. The result of the search is returned to you as the variable you named data

So…

// not this
Person.findById(personId, function(err, data) {
    this.favoriteFoods.push(foodToAdd).save();

// but this
Person.findById(personId, function(err, data) {
    data.favoriteFoods.push(foodToAdd).save();

That should resolve it.


#3

Thanks for the reply. I’ve changed “this” into “data”, which didn’t work. Also separated the “save” as it gave an error in the previous example. So, my code is now:

var findEditThenSave = function(personId, done) {
  var foodToAdd = 'hamburger';
  Person.findById(personId, function(err, data) {
    data.favoriteFoods.push(foodToAdd);
    data.save();
    if (err) {
      return done(err);
    }
    else {
      done(null, data);
    }
  });
};

Which results in the following error messages:

// running test
The item should be previously edited
// tests completed

and

Find-edit-update an item should succeed

and the Activity Log in Glitch.com says something about an Unhandled Promise Rejection Warning :no_mouth:


#4

this means you are not catching an error somewhere. Does your done callback handle the error?

Also, have you console.logged what the value of data is?

The docs state that you can resolve to a positive result, even if it doesn’t find one. So you may need to test for a null response.

However, mongoose translates findById(undefined) into findOne({ _id: null })

http://mongoosejs.com/docs/api.html#findbyid_findById

I won’t be much more help without seeing more of your codebase. You can post it here or link me to a git repo and I’ll take a look if you want. A repo would be better because I can then run my own tests instead of relying on what I think is happening.


#5

Added a console.log(data) and it looks normal. It’s only the next step, the .save(), that throws an error.

Here’s my code, any advice would be appreciated! https://glitch.com/edit/#!/join/67866323-53dd-44b9-85b7-eb0256fbdd18 :+1:

So frustrating if you keep staring at the same code and nothing …


#6

I’m not familiar with glitch, so you’ll have to give me some time. In the mean time, you could try this person’s solution

Don’t I know it! To lighten the mood, here is some comedic relief (or just facts??) lol

Every Programmer

introduction-to-software-coder-forge-john-mulhall-4-638

Is anybody out there?!

wisdom_of_the_ancients


Me like every day


#7

Ok, so the .save() method also returns a promise. So you have to handle that as well. This is why you were getting the Unhandled Promise Rejection Warning.

I added a console.log to the save method and extracted the message from the error object. You will now see a specific reason why it’s failing.

data.save((e, r) => {
      if(e) console.error('error saving data: ', e.message)
    });

#8

I’m also having issues with this one.

My code is:

var findEditThenSave = function(personId, done) {
  var foodToAdd = 'hamburger';
  
  Person.findById(personId, function(err, doc){
    
    if (err) throw err;
    
    console.log('Beginning of findById()' + doc);
    
    doc.favoriteFoods.push(foodToAdd);
    doc.markModified('favoriteFoods');
    
    console.log('after push() and markModified()' + doc);
    
    doc.save(function(err){
      if (err) {
        console.log("there's an error");
        done(err);
      }
    });
    
    done(null, doc);
  });
};

which results in this log on Glitch:

POST
Beginning of findById(){ name: ‘Poldo’,
age: 40,
favoriteFoods: [ ‘spaghetti’ ],
_id: 5b902fad24c4c56ef3d5741c,
__v: 0 }

after push() and markModified(){ name: ‘Poldo’,
age: 40,
favoriteFoods: [ ‘spaghetti’, ‘hamburger’ ],
_id: 5b902fad24c4c56ef3d5741c,
__v: 0 }
there’s an error
Error: Can’t set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11) …

And the FCC test says:

The item should be previously edited

and

Find-edit-update an item should succeed

which is confusing, because it was indeed edited as the console.logs show.


#9

Figured it out thanks to this fcc forum post. The only problem I had was that I was using two done(null, data). I should only write that once, within save(), and not within find(). Otherwise it sends the results of the find statement before saving.


#10

Thanks for posting this answer! Helped me a lot!


#11

I also had this same issue. My original code wouldn’t pass with the error - Find-edit-update an item should succeed.

Here is the code-

var findEditThenSave = function(personId, done) {
  var foodToAdd = "hamburger";
  Person.findById(personId, function(err, data) {
    if (err) {
      done(err);
    }

    data.favoriteFoods
      .push(foodToAdd)
      .save((err, data) => (err ? done(err) : done(null, data)));
  });
};

So I separated the data.favoriteFoods.push() and the data.save() and it now passes. Here is the updated code-

var findEditThenSave = function(personId, done) {
  var foodToAdd = "hamburger";
  Person.findById(personId, function(err, data) {
    if (err) {
      done(err);
    }

    data.favoriteFoods.push(foodToAdd);
    data.save((err, data) => (err ? done(err) : done(null, data)));
  });
};