Search code examples
mysqlnode.jsnode-mysql2

How to return mysql data to caller? Something works, other case don't work?


It is my db object code(DBO.js):

class DBO
{
    constructor(){
        let dbConfig = require('./config');
        dbConfig["multipleStatements"]=true;
        const moment = require('moment');
        const mysql = require('mysql2');
        const connection = mysql.createConnection(dbConfig);
        
        this.getITOList=(year,month,callBack)=>{
            const startDateString=year+"-"+month+"-01";
            const endDateString=moment(startDateString).add(1,"M").add(-1,"d").format('YYYY-MM-DD');
            
            let sqlString ="SELECT join_date,leave_date,ito_info.ito_id,post_name,ito_name,available_shift,working_hour_per_day,black_list_pattern from ";
            sqlString+="ito_info inner join black_list_pattern ";
            sqlString+="on ito_info.ito_id=black_list_pattern.ito_id ";
            sqlString+="where join_date<=? and leave_date >=? ";
            sqlString+="order by ito_info.ito_id";
            console.log("startDateString="+startDateString+",endDateString="+endDateString);
            connection.execute(sqlString,[startDateString,endDateString],(err, results, fields)=>{
                connection.end(err=>{
                    if (err) {
                        throw err;
                    } else {
                        callBack(err,results);
                        console.log("Get ITO List successfully.");
                    }
                });
            });
            
        }
        this.getRosterRule=(callBack)=>{
            let sqlString ="select * from roster_rule order by rule_type,rule_key,rule_value";
            connection.execute(sqlString,(err, results, fields)=>{
                connection.end(err=>{
                    if (err) {
                        throw err;
                    } else {
                        callBack(err,results);
                        console.log("Get Roster Rule successfully!");
                    }
                });
            });
        }
        this.close=()=>{
            connection.end(err=>{
                if (err) throw err;
                console.log("Disconnect form "+process.env["DATABASE_HOST"]+" successfully!");
            });
        }       
    }
}
module.exports = DBO;

Here is the RosterRule Object:

class RosterRule{
    constructor(){
        let DBO=require("../utils/dbo.js");
        let dboObj=new DBO();
        this.essentialShiftList=null;   
        this.maxConsecutiveWorkingDay=0;
        this.shiftHourCount={};     
        dboObj.getRosterRule((err,resultList)=>{
            if (err){
                throw err;
            }else {
                resultList.forEach(result=>{
                    switch (result.rule_type){
                        case 'ConsecutiveWorkingDay':
                            this.maxConsecutiveWorkingDay=parseInt(result.rule_value);
                            break;
                        case 'shiftHour':
                            this.shiftHourCount[result.rule_key]=parseFloat(result.rule_value);
                            break;
                        case 'shiftList':
                            var temp=result.rule_value.replace(/"/g,'');
                            this.essentialShiftList=temp.split(',');
                            break;
                    }
                });
            }
        });
        
    }
}
module.exports =new RosterRule();

Here is an ITO Object.

class ITO
{
    constructor(){
        /**
         * The ITO Id of the specified ITO.
         */
        this.itoId="";
        /**
         * The name of the specified ITO.
         */
        this.itoName="";
        /**
         * The post name of the specified ITO
         */
        this.postName="";
    
        /**
         * The total no. of working hour per day for the specified ITO.
         */
        this.workingHourPerDay=0.0;
        /**
         * The join date of the specified ITO.
         */
        this.joinDate=null;
        /**
         * The leave date of the specified ITO.
         */
        this.leaveDate=null;
        /**
         * The available shift list of the specified ITO.   
         */
        this.availableShiftList=[];
        /**
         * The black listed shift pattern list of the specified ITO.    
         */
        this.blackListedShiftPatternList=[];        
    }
    static getITOList(year, month){
        let DBO=require("../utils/dbo.js");
        let dboObj=new DBO();
        let resultObj={};
        dboObj.getITOList(year,month,(err,resultList)=>{
            if (err){
                throw err;
            }else {
                resultList.forEach(ito=>{
                    let itoObj;
                    if (resultObj[ito.ito_id]){
                        itoObj=resultObj[ito.ito_id];
                        itoObj.blackListedShiftPatternList.push(ito.black_list_pattern);
                    }else {
                        itoObj=new ITO();
                        itoObj.itoId=ito.ito_id;
                        itoObj.itoName=ito.ito_name;
                        itoObj.postName=ito.post_name;
                        itoObj.workingHourPerDay=ito.working_hour_per_day;
                        itoObj.joinDate=new Date(ito.join_date);
                        itoObj.leaveDate=new Date(ito.leave_date);
                        itoObj.availableShiftList=ito.available_shift.split(",");
                        itoObj.blackListedShiftPatternList.push(ito.black_list_pattern);
                    }
                    resultObj[ito.ito_id]=itoObj;
                });
                console.log("hi:"+JSON.stringify(resultObj));
                return resultObj;               
            }
        });
        
    }
}
module.exports = ITO;

Finally, this is RosterManager object code:

class RosterManager
{
    constructor(){
        let DBO=require("../utils/dbo.js");
        let ITO=require("./ITO.js");
        const RosterRule = require('./RosterRule');
        this.getRosterList=(year,month)=>{
            console.log("RosterRule:"+RosterRule);
            let itoList=ITO.getITOList(year,month);
            console.log(itoList);
        }
    }
}
module.exports = RosterManager;

All the RosterRule attributes can be load from DB successfully.

When the RosterManager.getRosterList is called, Why the return value is "undefined"?

I have added the following statement in ITO, the DBO object has got the data from DB succesfully.

console.log("hi:"+JSON.stringify(resultObj));

However, in the RosterManager object cannot read the data.

Would you help to fix it?


Solution

  • Wrap the query in a promise. Also avoid adding require() within your code. Instead leave it at the start of the file, rather than having it called mid-execution of your code.

    Also if you are going to use so many classes maybe consider typing everything with typescript.

    In ITO class:

    static getITOList(year, month){
      let DBO=require("../utils/dbo.js");
      let dboObj=new DBO();
      let resultObj={};
      return new Promise((resolve, reject) => {
        dboObj.getITOList(year,month,(err,resultList)=>{
          if (err){
              reject(err);
          } {
              resultList.forEach(ito=>{
                  let itoObj;
                  if (resultObj[ito.ito_id]){
                      itoObj=resultObj[ito.ito_id];
                      itoObj.blackListedShiftPatternList.push(ito.black_list_pattern);
                  }else {
                      itoObj=new ITO();
                      itoObj.itoId=ito.ito_id;
                      itoObj.itoName=ito.ito_name;
                      itoObj.postName=ito.post_name;
                      itoObj.workingHourPerDay=ito.working_hour_per_day;
                      itoObj.joinDate=new Date(ito.join_date);
                      itoObj.leaveDate=new Date(ito.leave_date);
                      itoObj.availableShiftList=ito.available_shift.split(",");
                      itoObj.blackListedShiftPatternList.push(ito.black_list_pattern);
                  }
                  resultObj[ito.ito_id]=itoObj;
              });
              console.log("hi:"+JSON.stringify(resultObj));
              resolve(resultObj);               
          }
        });
      });
    }
    

    In rostermanager

    constructor(){
      let DBO=require("../utils/dbo.js");
      let ITO=require("./ITO.js");
      const RosterRule = require('./RosterRule');
      this.getRosterList=(year,month)=>{
          console.log("RosterRule:"+RosterRule);
          ITO.getITOList(year, month).then(itoList => {
            console.log(itoList);
          }).catch(err => {
            // handle error
          });
      }
    }