mongoDB: TypeError: done is not a function

I’m really tired of seeing TypeError: done is not a function in every single function i build in the mongo sections of FCC in glitch. I pass the tests and when i hit submit i see no errors but if i run it on my own database i get the error every single time?

I don’t understand done, except that if i don’t put it in i don’t pass the tests and if i do put it in i get errors all over the place when i’m using my own database. Anybody willing to help me out to understand this?

var findAndUpdate = function(personName, done) {
  var ageToSet = 20;
  Person.find({name: personName}, function(err, data) {
    console.log(data)
    done(null, data);
  })
};

This one here passes the tests but again if i use it on my own database i get errors again.

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

anybody able to help me out with understanding this?

Can we see how do you call this handler functions in your own code and the error you get?

I am still learning this section and I am not the best person to answer this, but according to my understanding, done() is a callback function and it gets executed after the db operation you have done such as inserting, updating etc. Since these operations are asynchronous it is important to have such a callback. Take a look at your server.js file in the Glitch project to see how these handle functions are being called and how done() callback is used there

Thanks for helping out, maybe its supposed to error? things seem to update on my database and when FFC does its test no errors appears. I just hate seeing the red errors when i’m trying to play with my database.

also, i do have data in the database and the console.log statement in my code works fine.

Here is the code:

var mongoose = require('mongoose')
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });

const personSchema = new mongoose.Schema({
  name: String,
  age: Number,
  favoriteFoods: [String]
})

var Person = mongoose.model('Person', personSchema)

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

Here is the error:

events.js:174

11:22 PM

throw er; // Unhandled ‘error’ event

11:22 PM

^

11:22 PM

11:22 PM

TypeError: done is not a function

11:22 PM

Jump Toat /app/myApp.js:212:7

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:4837:16

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/helpers/promiseOrCallback.js:24:16

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:4860:21

11:22 PM

at model.$__save.error (/rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:491:7)

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/kareem/2.3.1/node_modules/kareem/index.js:315:21

11:22 PM

at next (/rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/kareem/2.3.1/node_modules/kareem/index.js:209:27)

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/kareem/2.3.1/node_modules/kareem/index.js:182:9

11:22 PM

at process.nextTick (/rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/kareem/2.3.1/node_modules/kareem/index.js:507:38)

11:22 PM

at process._tickCallback (internal/process/next_tick.js:61:11)

11:22 PM

Emitted ‘error’ event at:

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:4839:13

11:22 PM

at /rbd/pnpm-volume/c485ef13-7bbe-4074-961c-4b5006de9006/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/helpers/promiseOrCallback.js:24:16

11:22 PM

[… lines matching original stack trace …]

11:22 PM

at process._tickCallback (internal/process/next_tick.js:61:11)

The error is because you are calling the method below way but you are not passing the done() callback to the funciton.

Instead call your function like below.

findEditThenSave(‘5e8c594dded3d727bce55960’, (err,data)=>{
       if(err) console.error(err);
       //do what you want to do after the operation completes.
       console.log('Data item is modified and saved in the db')
});

sorry, i’m not picking this up at all. What you just wrote doesn’t even have done() in it. If i don’t have it in mine the FCC test doesn’t work but than again yes i don’t get the pile of errors.

its one or the other it seems lol

You’ve specified that the findEditThenSave function it should take a callback (done).

When you call the function, you are not passing that callback:

findEditThenSave('5e8c594dded3d727bce55960')

So when the function runs, it tries to run done(null, data), but in your function, because it hasn’t been passed in, done is undefined, not a function.

Just to solidify this. I could build a function that would render information somewhere for the user. Then I could pass this function as callback and set it to run at the end of my database function so it only displays the data after the data has been retrieved?

This is similar to chaining functions with .then except now you just put it at the end of your function instead of chaining it?

1 Like

No it’s simpler than that, you’ve written a function that needs two arguments, you’re only giving it one when you call the function, so it breaks. It’s supposed to be run in (I assume) a Node function, where you’d pass done to it, you don’t seem to be doing that

I think the mongo/node section of FCC needs to explain better why passing the done function in as a argument is so important. I don’t see a reason for it but i’ll research it a bit more and hopefully come to a understanding

Thanks a lot guys for helping me out. definitely had me a little perplexed

Hi @Jason_Eliasen What you said regarding chaining with .then (Promise) is similar to using a callback. But I believe NodeJS commonly use callbacks rather than using Promises. (I can be wrong here)
I suggest you read below articles for extra clarification.

Callbacks Vs Promises and basics of JS

What are callbacks in NodeJS

And once you get the hang of it you can try below
Writing neat asynchronous Node JS code with Promises