Search code examples
node.jses6-promise

NodeJS - Promise Return Values are not received properly


Problem: I'm supposed to get the proper objects which i'm resolving from promises. But I'm getting empty objects at the very end. SQL Queries which I'm executing are working flawless. Only thing is the proper return value.

Debugging: When i try to console the object value before resolving it; is saying "[Promise {}]".

Output I'm getting:

{
    "status": true,
    "data": [
        {},
        {}
    ],
    "errors": null,
    "msg": "Hahaha"
}

Code

export const executeAllQueries = (allQueries) => {
    return allQueries.map ( async productQuery => {
        try {
            let res = await executeProductQuery (productQuery);
            console.log(res); 
            return res;
        } catch (error) {
            console.log(error);
            return error;
        }
    })
}

const executeProductQuery = async (productQuery) => {

    let parentResponse = await new Promise ((resolve, reject) => {
        mysql.query( productQuery.parent.sql , productQuery.parent.data, (parentError, parentResult) => {
            if (parentError)
                reject ( { status: false, parent_sku: productQuery.parent.data[1], error: parentError.message } )
            else {
                resolve( { status: true,  parent_sku: productQuery.parent.data[1], parent_id: parentResult.insertId , error: null } )
            }
        })
    }); 

    if (parentResponse.status === true)
    {
        let variantPromises = productQuery.varients.map (async varientQuery => {
            try {
                return await executeVariantQuery(varientQuery, parentResponse.parent_id)
            } catch (error) {
                console.log(error);
                return error;
            }
        }); 

        return { parent: parentResponse, varient: variantPromises }
    }
}

const executeVariantQuery = async ( varientQuery, parent_id ) => {

    let varientResponse = await new Promise ((resolve, reject) => {
        varientQuery.varient.data[11] = parent_id; 
        mysql.query(varientQuery.varient.sql, varientQuery.varient.data, (varientError, varientResult) => {
            if (varientError)
                reject ( { status: false, error: varientError.message } )
            else {
                resolve( { status: true, varient_id: varientResult.insertId , error: null } )
            }
        })
    })

    if (varientResponse.status === true) {
        let attributePromises = varientQuery.attributes.map(async attribQuery => {
            try {
                return await executeAttributeQuery(attribQuery);
            } catch (error) {
                console.log(error);
                return error; 
            }
        })
        return { varient: varientResponse, attributes: attributePromises }
    }
}

const executeAttributeQuery = async (attribQuery) => {
    let attribResponse = await new Promise((resolve, reject) => {
        mysql.query(attribQuery.sql, attribQuery.data, (attribError, attribResult) => {
            if (attribError)
                reject ( { status: false, error: attribError.message } )
            else {
                resolve( { status: true, varient_id: attribResult.insertId , error: null } )
            }
        })
    })
    return attribResponse; 
}

Executing the the top method executeAllQueries() as following:

let completeVariants = isolateVariantProducts(fileRows); // All products are isolated in separate groups. Each group has a parent and it's variants.
let allQueries = generateCompleteQueriesForVariant(completeVariants);
let responses = executeAllQueries(allQueries);

res.status(200).json({status: true, data: responses, errors: null, msg: 'Hahaha'})

Runnable NodeJS Snippet:

let allQueries = [{parent: 1, varients: [1,2,3,4]}, {parent: 2, varient: [5,6,7,8]}]

const executeAllQueries = (allQueries) => {
    return allQueries.map ( async productQuery => {
        try {
            return await executeProductQuery (productQuery);
        } catch (error) {
            return error;
        }
    })
}

const executeProductQuery = async (productQuery) => {

    let parentResponse = await new Promise ((resolve, reject) => {
        if (true)
            resolve({ status: true, parent: productQuery.parent, msg: "Resolved"})
        else
            reject({status: false, parent: productQuery.parent, msg: "Rejected"})
    }); 

    if (parentResponse.status === true)
    {
        let variantPromises = productQuery.varients.map (async varientQuery => {
            try {
                return await executeVariantQuery(varientQuery)
            } catch (error) {
                return error;
            }
        }); 

        return { parent: parentResponse, varient: variantPromises }
    }
}

const executeVariantQuery = async ( varientQuery ) => {

    let varientResponse = await new Promise ((resolve, reject) => {
        if (true)
            resolve ( { status: true, msg: "Resolved" } )
        else {
            reject ( { status: false, msg: "Rejected" } )
        }
    });
    return varientResponse; 
}

console.log(executeAllQueries(allQueries));

Solution

  • executeAllQueries returns array of promises. You should do Promise.all() to get results.

    // Instead of
    let responses = executeAllQueries(allQueries);
    
    // do
    
    let responses = await Promise.all(executeAllQueries(allQueries));