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

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:

1 Like

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.

2 Likes

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:

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 })

Mongoose v8.0.2: Redirect to API

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.

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 …

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

8 Likes

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)
    });
1 Like

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.

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.

27 Likes

Thanks for posting this answer! Helped me a lot!

1 Like

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)));
  });
};
17 Likes

Your error is a simple .push error, since push return the new length of the array, .save is not defined.

you should push and then data.save()

2 Likes

You should just call done(err, data) insinde the

.save()

method callback.

Sadly, the page you referenced does not exist anymore.

Person.findById(personId, function(err, data){
    
    data.favoriteFoods.push(foodToAdd);
    console.log(data);
    data.save(function(err, data){
      done(null, data);
    });  
    
  });
2 Likes

Thank you so much, this was a Lifesaver! Even though the referenced post doesn’t exist I had the same issue with writing done(null, data) twice.

this is working
var findEditThenSave = function(personId, done) {
var foodToAdd = “hamburger”;

Person.findById(personId, (err, data) => {
console.log(“data”, data.favoriteFoods);
data.favoriteFoods.push(foodToAdd);
// data.markModified(“favoriteFoods”);
data.save((err, data) => {
if (err) {
done(err);
}
done(null, data);
});
});
}

Thank you! This is a big help!

1 Like

Thank you so much, if I didn’t find your answer about only using .done() once I think I would have been stuck forever. The “lessons” in the fcc challenges don’t make this clear at all.

My working answer -

var findEditThenSave = function(personId, done) {
  console.log(personId)
  let foodToAdd  =  "hamburger";
  Person.findById({_id:personId},async (err,data)=>{
    data.favoriteFoods.push(foodToAdd)
    await data.save();
    done(null,data);
  })
};```
2 Likes