Home > front end >  Is there any way to use the values(Boolean) of two Callback functions in Node.js?
Is there any way to use the values(Boolean) of two Callback functions in Node.js?

Time:12-05

Here is my Problem:

I need to write a Test in Node.js for a function, which select the data from database. It returns the value by using a callback function.(Code is down below.)

getCompanyById(id, callback) {
        let company = null;
        this.db.query("SELECT * FROM Company where id=?", id)
            .on('result', function (data) {
                company = data;
            })
            .on('end', function () {
                callback(company);
            });
 }

What I want to do in the Test function is:

  1. Test this function with all id(here 1 and 2);
  2. If all the Tests passed, console.log("Test for getCompanyById() passed").

And here is the original version of my test Code.

function testGetSchoolAdministrationById() {
  var pass1,pass2;
  databaseConnection.getSchoolAdministrationById(1, function (schoolAdministration) {
      if(schoolAdministration.first_name == "Harald" &&
            schoolAdministration.last_name == "Schmidt" &&
            schoolAdministration.id_schoolAdmin == 1)
         pass1=true;
    }
  );
  databaseConnection.getSchoolAdministrationById(2, function (schoolAdministration) {
      if(schoolAdministration.first_name == "Madeline" &&
            schoolAdministration.last_name == "Müller" &&
            schoolAdministration.id_schoolAdmin == 2)
           pass2=true;
    }
  );
  console.log("Test for getCompanyById() passed: "   (pass1 && pass2));
}

But it returns "undefined". After I searched on Internet, I realized that Node.js is Asynchrony and it won't work this way. console.log("..") have already finished, while the callback have not yet. Also I have seen Answers, like use another Callback function to deal with the value. But in my case I have 2 Callbacks and no idea how to do it.

So here is my question:

  1. Is there any ways to achieve the goal of the function testGetSchoolAdministrationById() without changing the function getCompanyById(id, callback)?(Cause this has a quite big influence to other Codes.)

  2. If the 1. question is not possible, is there any ways to achieve the goal, while the function getCompanyById(id, callback) can be changed? In other word, is there any better ways to achieve the same goal of getCompanyById(id, callback) without using callbacks?

  3. Or maybe a Test Framework will help this? I'm not using any Test Framework, cause I haven't tried and I' not really familiar to those.

This is my first Project about Node.js, so I am not very confident about any concept I mentioned above. So any suggestions and answers are welcomed. And since this is also my first question on Stack overflow, any suggestions about the questions/title/structure are also welcomed. Hope that, I described this clearly. I really want to figure this out.

CodePudding user response:

You mean to log the string once the test done?

Well you have to use nested callbacks to make it in your desired order.

So after first id in db check is done, proceed for next id check inside of the first id callback.


function testGetSchoolAdministrationById() {
  var pass1,pass2;
  databaseConnection.getSchoolAdministrationById(1, function (schoolAdministration) {
     
      if(schoolAdministration.first_name == "Harald" &&
            schoolAdministration.last_name == "Schmidt" &&
            schoolAdministration.id_schoolAdmin == 1){

            pass1=true;
            databaseConnection.getSchoolAdministrationById(2, function (schoolAdministration) {
            if(schoolAdministration.first_name == "Madeline" &&
                schoolAdministration.last_name == "Müller" &&
                schoolAdministration.id_schoolAdmin == 2){
               pass2=true;
            
               console.log("Test for getCompanyById() passed: "   (pass1 && pass2));      
               
              }
             else {
               console.log("Test for getCompanyById() passed: "   (pass1 && pass2));
             }
            }
          );
       }
       else {
          console.log("Test for getCompanyById() passed: "   (pass1 && pass2));
       }
    }
  );
  
}

CodePudding user response:

You can achieve this easily by using Promises.

One method would be making use of async/await keywords.

async function testGetSchoolAdministrationById() {
  try {
    const pass1 = await new Promise((resolve) => {
        databaseConnection.getSchoolAdministrationById(1, function(schoolAdministration) {
          resolve(schoolAdministration.first_name == "Harald" &&
            schoolAdministration.last_name == "Schmidt" &&
            schoolAdministration.id_schoolAdmin == 1);
        });
      }),
      pass2 = await new Promise((resolve) => {
        databaseConnection.getSchoolAdministrationById(2, function(schoolAdministration) {
          resolve(schoolAdministration.first_name == "Madeline" &&
            schoolAdministration.last_name == "Müller" &&
            schoolAdministration.id_schoolAdmin == 2);
        })
      });
    console.log("Test for getCompanyById() passed: "   (pass1 && pass2));
  } catch (e) {
    console.error(e);
  }
}

Or with a Promise.all(arrPromises).then(results) call

function testGetSchoolAdministrationById() {
  Promise.all([new Promise((resolve) => {
    databaseConnection.getSchoolAdministrationById(1, (schoolAdministration) => {
      resolve(schoolAdministration.first_name == "Harald" &&
        schoolAdministration.last_name == "Schmidt" &&
        schoolAdministration.id_schoolAdmin == 1);
    });
  }), new Promise((resolve) => {
    databaseConnection.getSchoolAdministrationById(2, (schoolAdministration) => {
      resolve(schoolAdministration.first_name == "Madeline" &&
        schoolAdministration.last_name == "Müller" &&
        schoolAdministration.id_schoolAdmin == 2);
    })
  })]).then(([pass1, pass2]) => {
    console.log("Test for getCompanyById() passed: "   (pass1 && pass2));
  });
}
  • Related