# Working on mongo DB: need an explanation

**URL:** <https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131>\
**Category:** General\
**Created:** [June 2, 2021, 6:15pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131 "2021-06-02T18:15:54Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 2, 2021, 6:15pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/1 "2021-06-02T18:15:55Z")

</div>

Hallo,  
I am currently working on a challenge and at the moment I need to implement a code doing this actions:  
1-check if a username is in the database  
2–is so, return “username exists”  
3-if not add the username

I have created this function for searching the database  
(User is the mongoose model)

```auto
const findUser = function(user) {
  User.findOne({username : user},function(err, userFound){
    if(err) return res.json({err: "search failed"});
    else return userFound;
     })
};

```

but if I test with a user already existing (I saw it in the db collection),

```auto
console.log(findUser("existing-user")); //it prints "undefined"

```

what am i doing wrong?  
in the findUser function, do i Have to return the UserFound or can I just return true/false?

thanks

---

<div class="post-metadata">

**Author:** ![Sky020](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sky020/32/128093_2.png) [@Sky020](https://forum.freecodecamp.org/u/Sky020)\
**Post date:** [June 3, 2021, 10:28am UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/2 "2021-06-03T10:28:54Z")

</div>

Hey again 👋

This is an issue of scoping. Think about:

- What you want to return
- Where you want to return
- When you want to return

Examples:

- Equivalent to what you currently have:

```javascript
function num1() {
  return "I am from 1";
}
function findOne(callback) {
  // I am a simple example implementation of Mongoose's
  // Model.findOne function
  return callback();
}

function num2() {
  findOne(num1);
}

const resultOfNum2 = num2();
console.log(resultOfNum2);

```

Give that a run in your favourite text editor/browser.

- What you want:

```javascript
function num1() {
  return "I am from 1";
}
function findOne(callback) {
  // I am a simple example implementation of Mongoose's
  // Model.findOne function
  return callback();
}

function num2() {
  return findOne(num1); // Difference is here!
}

const resultOfNum2 = num2();
console.log(resultOfNum2);

```

* * *

Now, the above is an oversimplification, because it ignores the _“when”_.

Database logic (in-fact, most server logic too) is asynchronous. So, now you need to consider when a function should be `async`, and when you need to `await` a few YouTube tutorials on how common apps like this are built, and look at a few examples in decent documentation. I suspect Mongoose has some full examples.

Hope this helps

---

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 3, 2021, 12:14pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/3 "2021-06-03T12:14:29Z")

</div>

ok, I understood the code bove was lacking of the return statement and I modified the find() method accordingly. in this was

```auto
var findUser = function(user) {
  let result;
  User.findOne({username : user},function(err, data){
    if(err) return "search failed";
    else result=data;    
  })
  return result;
};

app.post('/api/users', function(req, res) {
    let searchResult = findUser(req.body.username);
    if(searchResult!=null) {
        return console.log("username already exists") ;
    } else {
         var newUser = new User({username : req.body.username});
          newUser.save(function (err, data){
               if(err) return res.json({err: "saving failed"});
               else return res.json({username: req.body.username, _id: data._id.toString()});      
    })
    }
})

```

however the test does not occur and I get the username logged in the db even if is already exists.  
Before I used this findOne() function and I could console log the correct result that , however, is not considered in the app.post

```auto
var findUser = function(user) { 
  User.findOne({username : user},function(err, data){
    if(err) return "search failed";
    return console.log(data);    
  })  
};

```

I tested it just calling the function with a brand new user name  
console.log(findUser(“newuser”); //null  
console.log(findUser(“existingone”); //user object  
and on the console it displayed “null”, that’s why in the app.post I used this condition to decided it to add a new user or if to display that user already exists

---

<div class="post-metadata">

**Author:** ![Sky020](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sky020/32/128093_2.png) [@Sky020](https://forum.freecodecamp.org/u/Sky020)\
**Post date:** [June 3, 2021, 1:52pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/4 "2021-06-03T13:52:55Z")

</div>

Again, you are dealing with asynchronous data. So, you cannot expect this to return anything but `undefined`:

```auto
var findUser = function(user) {
  let result; //1 - order line is executed
  User.findOne({username : user},function(err, data){
    if(err) return "search failed"; //3
    else result=data; //4
  })
  return result; //2
};

```

You need to define asynchronous functions, and await their responses:

```auto
async function someAsyncFunc() {
  return await someAsyncDBCall();
}
console.log(await someAsyncFunc()); // Technically, await
// cannot be used outside of an async function, but this
// is here to show the idea.

```

Hope this helps

---

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 3, 2021, 8:35pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/5 "2021-06-03T20:35:27Z")

</div>

ok, so if I write

```auto
var findUser = function(user) { 
  User.findOne({username : user},function(err, data){
    if(err) return "search failed";
    else return data;    
  })  
};

```

won’t work to define a generic “search” function to be called in different occasions? Do i then need to define the search IN each particular route/use?

---

<div class="post-metadata">

**Author:** ![Sky020](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sky020/32/128093_2.png) [@Sky020](https://forum.freecodecamp.org/u/Sky020)\
**Post date:** [June 3, 2021, 9:13pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/6 "2021-06-03T21:13:30Z")

</div>

> [@francesca.giammichel](#):
>
> won’t work to define a generic “search” function to be called in different occasions?

Correct. That function does nothing useful.

> [@francesca.giammichel](#):
>
> Do i then need to define the search IN each particular route/use?

I am not sure I understand what you mean with this…

I like looking at examples. So, here is an example:

```auto
const findingTheDoc = new Promise((res, _) => res("I took time to find"));

async function myFindOneDataBaseExample(callback) {
  // I find a document in a database model,
  // and return it through a callback.
  const randomExampleDoc = { name: "Francesca" };
  // To pretend this function takes time looking for an actual
  // document in a real database - not instant!
  const t = await findingTheDoc(); // Just takes time...
  return callback(null, randomExampleDoc);
}

async function myGetDocumentFunc(done) {
  return await myFindOneDataBaseExample((err, data) => {
    if (err) return //null so does not matter
    console.log(data);
    // DO something with the data!
    // Common: use a callback like 'done'
    // i.e. done(data);
    // OR, just return it, and use it within myGetDocumentFunc
    return data;
  });

// Within some other function (remember what I said about await outside a function...)
console.log(await myGetDocumentFunc());

```

This is a lot of abstract stuff, until you spend time writing the code 🙂

---

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 3, 2021, 10:01pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/7 "2021-06-03T22:01:20Z")

</div>

yes, that was not very clarifying, I am sorry ☹  
Unfortunately I have just lost ALL of my code (including the one that was working ☹ )  
it is ok to do it again but I was still stuck with that finding an item and then using the result of the finding.  
If I may dare, if could you please fix “my” code so that for me it is just easier to make my way to try to understand. I mean, I understand that some functions take time but nothing of that was mentioned and the example for searching the DB was something like this

```auto
var findPersonByName = (personName, done) => {
   Model.find({user : user}, function(err, data) {
    if(err) return console.log(err);
   else done(null, data);
  }
}

```

i tried this , too but again with no success. Unfortunately I have not found a decent video on youtube (and I prefer reading rather than watching) so I am stuck because the “done” stuff has appeared here for the firt time.  
so, for the moment I am in the app.post, got the parameter to find, written the findOne function, but still struggling with using the resulting data (null if the username does not exists

```auto
app.post('/api/users', function(req, res){
  let user=req.body.username;
  let userFound = User.findOne({username:user}, function(err, data){
    if(err) return res.send("error");
    else return data;
  })
  if (userFound==null) {
    let newUser = new User({username:user});
    newUser.save(function(err, data){
      if(err) return res.send("error in saving");
      else return res.json({username:user})
    })  
  }
}) 

```

---

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 3, 2021, 10:02pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/8 "2021-06-03T22:02:21Z")

</div>

eventually I used this and works, but I would understand the concepts you tried to explain me

```auto
app.post('/api/users', function(req, res){
  let user=req.body.username;
  let findUser = User.findOne({username:user}, function(err, data){
    if(err) return res.send("error");
    else if (data!=null) return res.send("exists")
    else {
      let newUser = new User({username:user});
      newUser.save(function(err, data){
      if(err) return res.send("error in saving");
      else return res.json({username:user})
    })  
    }
  })   
}) 

```

---

<div class="post-metadata">

**Author:** ![Sky020](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sky020/32/128093_2.png) [@Sky020](https://forum.freecodecamp.org/u/Sky020)\
**Post date:** [June 4, 2021, 9:28am UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/9 "2021-06-04T09:28:16Z")

</div>

Hm… This is not something I particularly want to try teach any further, as it does presume a lot of prior knowledge (which you may very-well have, but I do not know what you know). So, best thing I can think is to give you some resources:

1. First mention of `await` in a Mongoose.js context: [Mongoose v8.0.2: Redirect to API](https://mongoosejs.com/docs/api.html#model_Model.findOne) (in the last line of the example)
2. For Mongoose.js **specifically** : [Mongoose v8.0.2: Queries](https://mongoosejs.com/docs/queries.html#queries-are-not-promises) - sounds like going with `async..await` and promises is not the safest option - can cause unwanted behaviour)

So, databases are probably not the best place to be learning about asynchronous JS. I frequently use it with MongoDB (no Mongoose.js), but that is just because I prefer the granularity MongoDB offers.

This is the first lesson in the fCC curriculum teaching Promises: [https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/es6/create-a-javascript-promise](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/es6/create-a-javascript-promise)

Then, search `Coding Train Async Await` in your favourite search engine, and you will find some excellent content on the matter.

* * *

Lastly, what you have done with the callback within `findOne` is perfectly fine. There is not reason to assign it to `findUser`, but the use of the callback is what is common. Your previous method:

```auto
var findUser = function(user) {
  let result; //1 - order line is executed
  User.findOne({username : user},function(err, data){
    if(err) return "search failed"; //3
    else result=data; //4
  })
  return result; //2
};

```

This involves something called _side-effects_ - not an ideal method, in most cases. You can search if you want to know more on the matter.

One thing:

> [@francesca.giammichel](#):
>
> ```auto
> if(err) return res.send("error");
> else if (data!=null) return res.send("exists")
> else {
> 
> ```

If `err` does not exist, is `data` not always **not** `null`?

---

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 4, 2021, 12:03pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/10 "2021-06-04T12:03:48Z")

</div>

I will DEFINITELY go back to the async and promise stuff: since I have not used it at all in my code experience I feel very awkward with it.

Regarding your last observation, and following one of our precedent conversation about error, I can see a logic for my code:  
-an error is something going wrong in the searching process

- otherwise we have some returned data that can be an user (if that user exist) or a null object if the user does not exist yet.  
Actually I came to the “Null” option because I console.log the result of an new username and I didn’t get an error but a Null.  
I have just tested it again and just with a if(err), else and and new user does not throw an error

btw, incredibly I finished the work… but I am struggling with the logs tests: I am scatching my ehad because the output is identical to the example page and I am not getting information from the developer tool , so far ☹

> **[Invitation to collaborate on boilerplate-project-exercisetracker-1](https://replit.com/login?goto=%2Fjoin%2Ftqnoxhkp-ranran2121)**
>
> Code together live on boilerplate-project-exercisetracker-1, a Node.js by ranran2121, with Repl.it multiplayer

I believe it is because of date formatting in the output json object when I perform the from-to query. I find different options but either  
1-I get the right format but all the optional query elements (from, to) appear even if they are not requested for example {"\_id":“60b7c2fb978d3d0527b817f8”,“username”:“ranran”,“from”:“Invalid Date”,“to”:“2013”,“count”:4,“log”:[{“description”:“mini”,“duration”:144,“date”:“Tue Feb 21 2012”},{“description”:“ermi”,“duration”:44,“date”:“Tue Feb 21 2012”},{“description”:“arya”,“duration”:23,“date”:“Tue Feb 21 2012”},{“description”:“athos”,“duration”:12,“date”:“Tue Feb 21 2012”}]}  
2-or i automatically get rid of the unrequested query elements but with uncorrect format, for example  
{"\_id":“60b7c2fb978d3d0527b817f8”,“username”:“ranran”,“to”:“2021-06-01”,“count”:4,“log”:[{“description”:“mini”,“duration”:144,“date”:“Tue Feb 21 2012”},{“description”:“ermi”,“duration”:44,“date”:“Tue Feb 21 2012”},{“description”:“arya”,“duration”:23,“date”:“Tue Feb 21 2012”},{“description”:“athos”,“duration”:12,“date”:“Tue Feb 21 2012”}]}

is there a way to accomplish that?

---

<div class="post-metadata">

**Author:** ![Sky020](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sky020/32/128093_2.png) [@Sky020](https://forum.freecodecamp.org/u/Sky020)\
**Post date:** [June 4, 2021, 12:42pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/11 "2021-06-04T12:42:09Z")

</div>

> [@francesca.giammichel](#):
>
> otherwise we have some returned data that can be an user (if that user exist) or a null object if the user does not exist yet.

My bad. This is correct.

---

<div class="post-metadata">

**Author:** ![francesca.giammichel](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/francesca.giammichel/32/208869_2.png) [@francesca.giammichel](https://forum.freecodecamp.org/u/francesca.giammichel)\
**Post date:** [June 4, 2021, 12:44pm UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/12 "2021-06-04T12:44:41Z")

</div>

> Blockquote  
> My bad. This is correct.

I know you were just testing me 😛

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/freecodecamp/original/3X/e/1/e1c433102e34b46dfaa3e15d13ab9a514b127078.svg) [@system](https://forum.freecodecamp.org/u/system)\
**Post date:** [December 4, 2021, 12:44am UTC](https://forum.freecodecamp.org/t/working-on-mongo-db-need-an-explanation/463131/13 "2021-12-04T00:44:51Z")

</div>

Closed on December 4, 2021, 12:44am UTC

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
