APIs > MongoDB and Mongoose > What is Done?

I am working on the API Course and I’ve been stuck on the 3rd challenge ‘Create and Save…’ for some time now. The problem I am having is that I don’t understand where the ‘done’ is coming from nor what I am supposed to be doing with it.

const createAndSavePerson = (done) => {
  done(null /*, data*/);
};

I stopped working on the challenges to try and figure out what it is meant to represent / do, but I am not finding anything that mentions it so I must not be looking in the right place. This feels like it is something I should really understand because each of the functions throughout the rest of this section uses ‘done’.

Not asking for anyone to explain it to me here, but wouldn’t be opposed. What I am hoping for is that maybe someone knows of a really good resource that would help me to understand.

I am certain I could stumble my way through this section and pass, but that wouldn’t really do me any good in the long run. I’d really like to have it ‘click’ for me.

Thanks!

The use of done is kind of explained in the second paragraph of the Create a Model challenge. What is not explained is when the tests for a particular challenge run, they are able to pass a function as an argument to your createAndSavePerson function. When you call done(null, data) , you are actually executing that passed function so the tests can perform some additional tasks. In the case of this challenge, the test takes the record you created (the person object) and removes it out of the database to make the database “clean” for the next time the test or another test runs.

For this particular challenge, the following is the function that is passed (you can find it in the server.js file.

function (err, data) {
    clearTimeout(t);
    if (err) {
      return next(err);
    }
    if (!data) {
      console.log("Missing `done()` argument");
      return next({ message: "Missing callback argument" });
    }
    Person.findById(data._id, function (err, pers) {
      if (err) {
        return next(err);
      }
      res.json(pers);
      pers.remove();
    });
  }

Thank you @RandellDawson.

Unfortunately, it’s still not clicking for me. I went ahead and looked at the answer for this challenge in order to draw connections between what I think I know about JS and callbacks and what you are showing me.

Might help me to try and talk this out a little bit (not that you need to keep answering me)

createAndSavePerson is a variable it’s value will be whatever is to the right of the ‘=’
The expression is an arrow function which would be equivalent to function fname()
done is an argument for these arrow functions.
done is a function itself.

When createAndSavePerson is evaluated, its value is the return value from the arrow function. Since it is a function that is being passed into the arrow function, the value of createAndSavePerson is the return value of the done() (uncertain, is a question below).

If assuming the above is correct so far, then seems like createAndSavePerson is either err or res.json for that person that was created (from your code snippet).

Questions:

  1. Is the return value of the arrow function the return value of the done()
  2. Is the /*, data*/ supposed to be uncommented?
  3. Is /*, data*/ commented out because if it wasn’t then we we get (below) from the start of these exercises ?

Continuing On…

If I am correct so far, then I know that within any function I can do stuff so all of my work would need to come before done is called. For this example, that means I need to write code for a new Person to be created and save that person in the db.

I don’t want to copy the solution code here, but I have looked at it. The save is odd to me and like others on that thread, I am struggling to confidently know what data is.

From the Mongoose docs, I do see that .save() can take a callback function as a parameter. The solution code appears to be doing that but not sure I follow.

My thought to this point (and I can try it but want to continue the thought process here first) is that I should be able to:

(async is needed as well)

let data = await myNewPerson.save();
done(null, data);

After the function, I did call it with createAndSavePerson();

This works when it comes to saving the person to the DB, but I get an error in the console so I am not actually sure that me calling the function as I did was correct.

TypeError: done is not a function

This kind of makes sense because I didn’t pass a function into the createAndSavePerson call. Considering this, I ran it again but this time I passed console.log as the function.

createAndSavePerson(console.log);

I didn’t get any errors this time but I have not submitted the challenge to see if it passes or not.

FYI - I submitted and passed the test.

https://replit.com/@wdpronovost/boilerplate-mongomongoose#myApp.js