2

I am creating an API that gets a product object as well as the variants of that product in one json object.

I am using this code to get the product:

const pool = require("../../config/db");

module.exports = {
    getProductById: (id, callBack) => {
        pool.query(
            `SELECT
                p.id,
                p.name,
                p.description,
                b.id as brand_id,
                b.name as brand_name
            FROM product p
            INNER JOIN brand b ON p.brand_id = b.id
            WHERE p.id = ?`,
            [
                id
            ],
            (error, results, fields) => {
                if (error) {
                    return callBack(error);
                }

                // This is where I would like to call the getProductById
                // function so that I can add the array to the below          
                // productObject

                var productObject = {
                    id: results[0].id,
                    name: results[0].name,
                    description: results[0].description,
                    brand: {
                        id: results[0].brand_id,
                        name: results[0].brand_name
                    }
                };

                return callBack(null, productObject)
            }
        )
    }
};

I would like to get the product variants from the api function I already created that look like this:

const pool = require("../../config/db");

module.exports = {
    getProductVariantsById: (id, callBack) => {
        pool.query(
            `SELECT *
            FROM product_variants
            WHERE product_id = ?`,
            [
                id
            ],
            (error, results, fields) => {
                if (error) {
                    return callBack(error);
                }

                return callBack(null, productObject)
            }
        )
    }
};

I am struggling to call the getProductVariantsById function async in the getProductById function.

I have tried using promises but I can't get it right. This is what I tried to do.

How can I achieve this?

2
  • 1
    Can you edit your question and show us how've tried using promises? Commented Dec 6, 2020 at 16:45
  • @eol I added the link that showed how to use promises. I removed the code I used :( Commented Dec 6, 2020 at 16:59

2 Answers 2

4
+50

If your pool.query is async you can just run with await

getProductById: async (id, callBack) => {
  ...
  await getProductVariantsById(id, callback);
}
getProductVariantsById: async (id, callBack) => {
  ...        
  await pool.query(...);
  ...
}

if not async, to use Promise you need smt like this

getProductVariantsById: async (id, callBack) => {
  return new Promise((resolve) => {
    pool.query(..)
    ...
    resolve();
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can convert callback to promise using util.promisify function and then use it in an async/await manner.

Here is the code sample:

I assume that your using mysql package for the database connection and NodeJS version which supports async/await:

const {promisify} = require('util');                                                                                    
const pool = require('../../config/db');                                                                                
                                                                                                                        
const getProductVariantsById = id => {                                                                                  
    return promisify(pool.query)('SELECT * FROM product_variants WHERE product_id = ?', [id]);                          
}                                                                                                                       
                                                                                                                        
const getProductById = async (id) => {                                                                                  
    const [products, variants] = await Promise.all([                                                                    
        // Assuming you're using 'mysql' package                                                                      
        promisify(pool.query)(`SELECT                                                                                   
                p.id,                                                                                                   
                p.name,                                                                                                 
                p.description,                                                                                          
                b.id as brand_id,                                                                                       
                b.name as brand_name                                                                                    
            FROM product p                                                                                              
            INNER JOIN brand b ON p.brand_id = b.id                                                                     
            WHERE p.id = ?`, [id]),                                                                                     
        getProductVariantsById(id),                                                                                     
    ]);
    

    // Note: What if a products array is empty? you should handle this case too.                                                                                                         
                                                                                                                        
    const productObject = {                                                                                             
        id: products[0].id,                                                                                             
        name: products[0].name,                                                                                         
        description: products[0].description,                                                                           
        brand: {                                                                                                        
            id: products[0].brand_id,                                                                                   
            name: products[0].brand_name                                                                                
        }                                                                                                               
        variants, // ... or whatever you wanna do with this array                                                       
    };                                                                                                                  
}                                                                                                                       
                                                                                                                        
module.exports = {                                                                                                      
    getProductVariantsById,                                                                                             
    getProductById,                                                                                                     
}; 

... You may also consider handling all this logic in an SQL query by adding JOIN to the product_variants table

Comments

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.