0

I hope the following code snippet is enough to explain my problem:

function getChildrensRoomsProductNumbers(uuids, callback) {
        var productNumbers = [];
        uuids.forEach(uuid => getProductNumber(uuid, function(productNumber){
            productNumbers.push(productNumber);}))
        callback(productNumbers);
    }

So for an array of uuids, I'd like to request the corresponding product numbers from an online shop and store them in the array productNumbers which then I'd like to pass to a parent function for further manipulation through calling callback(productNumbers)

The request itself is done in the getProductNumber function.

However, I don't understand why the array productNumbers is empty? I know forEach is not returning anything so that's why I prepared an array beforehand that should be filled in my idea.

I'm relatively new to NodeJS/JavaScript, so I probably might be missing some basic concepts here.

This is the getProductNumber function:

function getProductNumber(uuid, callback){
    getToken(function(err, token){
        var headers = {
            'Authorization': 'Bearer ' + token,
            'Content-Type': 'application/json',
        };
        const options = {
            url: BASE_URL + 'api/product/' + uuid,
            method: 'GET',
            headers: headers
        };

        axios.request(options)
            .then(res => {
                console.log("NUmber: " + res.data.data.productNumber);
                callback(res.data.data.productNumber);
            })
            .catch(err => {
                console.error(err.response);
            });
        })
}
3
  • its seems like your getProductNumber is an async function, so your callback will be called directly before awaiting the result of your getProductNumber Commented Jan 6, 2022 at 14:41
  • is there a way to wait for the result without using the async/await concept? Commented Jan 6, 2022 at 14:47
  • there is the .then() method Commented Jan 6, 2022 at 14:50

2 Answers 2

2

please first learn async/await style to get rid of callbacks

then this will be doable :

    async function getChildrensRoomsProductNumbers(uuids) {
        var productNumbers = [];
        for (let uuid of uuids) {
            const productNumber = await getProductNumber(uuid);
            productNumbers.push(productNumber);
        }
        return productNumbers;
    }

like people said in comments getProductNumber looks like it does an async job. if you wat to stick with callbacks you can use https://www.npmjs.com/package/async to fire a callback when your loop is done.

Sign up to request clarification or add additional context in comments.

4 Comments

That's actually the way I'd like it to do but I'm extending an existing tool that was written some time ago and the problem is that the request function for the token to the shop system doesn't work with async/await but expects a callback to which the token will be provided
you can encapsulate a callbacky function with : const util = require('util'); const awaitablegetProductNumber = util.promisify(getProductNumber); that way you can call await awaitablegetProductNumber (uuid)
How would I change the getProductNumber function which expects a callback function as well? I edited the above post with the getProductNumber function for better understanding.
Thanks for introducing the util.promisify() function to me. That was new to me. Therefore, I realized it was easier to promisify the getToken() function that I have to obtain the shop api token. I then continued to have to other functions to work with the await/async principle.
0

Thanks to @Raphael PICCOLO for pointing out the util.promisify function.

On that basis, I promisified the function which I have to obtain the shop api token and have the rest to work with async/await, like so:

const awaitablegetToken = util.promisify(getToken);

async function getChildrensRoomsProductNumbers(uuids) {
    var productNumbers = [];
    var accessToken = await awaitablegetToken();
    for (const uuid of uuids){
        const productNumber = await getChildrensRoomsProductNumber(uuid, accessToken)
        productNumbers.push(productNumber);
    }
    return productNumbers;
}

3 Comments

It would be fair to upvote and accept the other answer rather than provide your own that basically copies it.
Well, yes I was just going to do it. I just thought it would be helpful to provide the exact complete (code) solution to my question now which I could't have done as a comment to the answer?
It's perfectly fine if you also reward someone's effort and accept their answer. It's ok now. Regards.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.