0

I get some data from mongodb using mongoose find() and perform some validation on that data, but the problem is that this function is async and it does not wait for the data to be completed and execute the next code. and when the next code is executed it enables to perform because it has null data. then i wrote my validation logic in the async function so that when data is available only then it move to next code but on every return it sends undefined data.

function isValidObject(obj) {

     schemaData.find({}, (error, data) => { // calls data from db

      var contactSchema = data; // this is data i need

    if(//validation fails){
      return "wrong data";// every time it returns undrfined on every 
                          // condition
     }

     });                         
 }

var validationResp = isValidObject(obj);
console.log(validationResp); // output is undefined

i also used "await" to wait for the data, but in that case it return [object promise] on every return statement

Raza Ellahi
  • 63
  • 2
  • 11

4 Answers4

2

use async/await

In your case:

async function isValidObject(obj) {
  let data = await schemaData.find({}); // wait until it resolve promise 
  //do your validaion    
  return data;                  
}

isValidObject(obj).then((validationResp)=>{console.log(validationResp)});
Boobalan
  • 795
  • 1
  • 5
  • 14
  • some of the problem solves, but now isValidObject(obj) also behaves like async function, how to make it also wait for response and then allow the next code to execute. – Raza Ellahi Mar 22 '19 at 07:20
  • Simply mark the parent function as async and use await keyword before isValidObject() – Boobalan Mar 22 '19 at 07:22
  • actually it is wrapped in a function like this exports.uploadContact = (req, res) => { upload(req, res, function (err) { csv .fromString(req.file.buffer.toString(), {}).on("data", function (data) { isValidObject(data).then((res) => {} }).on("end", function () {} .... } – Raza Ellahi Mar 22 '19 at 07:45
  • exports.uploadContact = (req, res) => { upload(req, res, function(err) { csv .fromString(req.file.buffer.toString(), {}) .on("data", async function(data) { const res = await isValidObject(data); //wait //validate //proceed }) .on("end", function() {}) }) } – Boobalan Mar 22 '19 at 08:03
1

use the then() method it return a promise

var promise1 = new Promise(function(resolve, reject) {
  resolve('Success!');
});

promise1.then(function(value) {
  console.log(value);
  // expected output: "Success!"
});

more details at MDN Using the then method

Ridha Rezzag
  • 3,672
  • 1
  • 34
  • 39
1

Are you familiar with "promises".You can use ".then(callback)". It will wait until async function is executed. And you can perform your validation in the callback function

 User.findById(id)
    .then(function(user) {
      if (!user) {
        return "here you return an error";
      }

      return "you return OK with payload from database";
    })
    .catch(next);
Șveț Denis
  • 11
  • 1
  • 3
1

What is happening in your case is that when you assign var validationResp = isValidObject(obj); the function isValidObject(obj) has not returned anything and has only scheduled a callback(This is a very important concept when working with callbacks). As pointed out above you need to use Promises. The below is an example of your case as to how you can use Promises.

function isValidObject(obj){

 return new Promise((resolve,reject) => {
   schemaData.find({}, (error, data) => { // calls data from db

      if(validation fails){
         reject(error)// every time it returns undrfined on every 
                      // condition
       }else{
         var contactSchema = data; // this is data i need
         resolve(data)// You can resolve the promise with the data directly instead 
        // of assigning it to a variable or you can use (resolve(contactSchema))
       }
    }) 
  })
}

After this when you want to use the data you can use do something like the below code snippet.

isValidObject(obj)
.then(result => {
    // Use the result object here. This is the result from the Database
 })
 .catch(error => {
   //Handle the Error 
 })
Apoorv
  • 622
  • 8
  • 22
  • when ever i used return statement in that function , it send [object promise], not the value that i mentioned – Raza Ellahi Mar 22 '19 at 08:01
  • Yes that is because you are returning from a Mongoose callback and Mongoose returns a `thenable` which is similar to a Promise but not exactly a promise. Did you try the code i posted ? If you face any issue with that please let me know – Apoorv Mar 22 '19 at 08:44