node.js async getting data from db

Viewed 283

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 Answers

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();
  }
}

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

Related