Home > Software design >  When I call a function in a Promise it doesn't work synchronous in ExpressJS
When I call a function in a Promise it doesn't work synchronous in ExpressJS

Time:11-10

I'm new at Node and what I'm trying to do here is call a function before the page rendered but my functions work after my page rendered and I can't get data coming from another function.

exports.getCity = (req, res) => {
    controlCity(req.params.city).then((control) => {

        res.render('index.ejs', control);

    })

}



const controlCity = async (cityStub) => {
    return new Promise((resolve, reject) => {
        City.findAll({ where: { SEHIRSTUB: cityStub } })
            .then(
                city => {
                    if (city.length === 0) {  // when it comes here it works
                        resolve({ value: "test" }); 
                    }
                    else {

                        resolve(controlPredictedWeather(city[0])); 
                    }

                }).catch(err => console.log(err));
    }
    )
}
const controlPredictedWeather = city => {

    Predicted_Weather.findAll({ where: { CITYID: city.ID } }).then(
        degree => {
            if (degree.length === 0) {
                return (getPredictedWeather(city)); // it goes another function
            }
            else {
                console.log({ value: degree[0], city: city });
                return { value: degree[0].degree, city: city };
            }
        }
    ).catch(err => console.log(err))
}

How can I solve this problem?

CodePudding user response:

The issue is that you don't return anything in controlPredictedWeather function

const controlPredictedWeather = city => {
//  vvv added return here
    return Predicted_Weather.findAll({ where: { CITYID: city.ID } }).then(
        degree => {
            if (degree.length === 0) {
                return (getPredictedWeather(city)); // it goes another function
            }
            else {
                console.log({ value: degree[0], city: city });
                return { value: degree[0].degree, city: city };
            }
        }
    ).catch(err => console.log(err))
}

Having solved the issue, now you can address the elephant in the room

  1. you have an async function with no await
  2. You're using the Promise constructor anti-pattern - i.e. new Promise where it's never required

Since you have used async keyword, that suggests you want to use the somewhat easier to read async/await pattern of using Promises

So, why not use it fully

Like this

exports.getCity = async (req, res) => {
    const control = await controlCity(req.params.city);
    res.render('index.ejs', control);
};

const controlCity = async (cityStub) => {
    try {
        const city = await City.findAll({ where: { SEHIRSTUB: cityStub } });
        if (city.length === 0) {  // when it comes here it works
            return { value: "test" }; 
        } 
        // no need for else since returning above
        return controlPredictedWeather(city[0]);
    } catch(err) {
        console.log(err);
    }
};
const controlPredictedWeather = async (city) => {
    try {
        const degree = await Predicted_Weather.findAll({ where: { CITYID: city.ID } });
        if (degree.length === 0) {
            return (getPredictedWeather(city)); // it goes another function
        }
        // no need for else since returning above
        console.log({ value: degree[0], city: city });
        return { value: degree[0].degree, city: city };
    } catch(err) {
        console.log(err)
    }
};

Of course, there is one elephant left in the room, and that is that control in

res.render('index.ejs', control);

WILL be undefined if either of .findAlls throw an error - this will also be the case in your original code, just thought I'd mention that

CodePudding user response:

Try async/await syntax it's much simpler.


async function fn() {
  try {
    let res = await response();
    doSomthingWith(res);
  }
  catch(e) {
    console.log('Error!', e);
  }
}
fn();

  • Related