Search code examples
jquerynode.jsexpresssap-conversational-ai

How to get res json value in Express.js


I am newbie in node.js. I am trying to do something like this -

I have created one Add To Cart API where i am first checking whether session cart exist or not. If not exist, i am creating new cart via getCartCode(res) method.

app.post('/addToCart', function(req, res) {
console.log('[POST] /addToCart');

var cart = req.body.conversation.memory['cart'];

if(!cart) {
   const response = getCartCode(res);
   console.log("******* Result ************ : " + response.conversation.memory['cart']); // Giving undefined exception here
}
}

getCartCode - This method create cart and return the code which i am returning via res.json

function getCartCode(res)  {

return createCart()
  .then(function(result) {
    res.json({
      conversation: {
        memory: {
          'cart': result,
        }
      }
    });

    return result;
  })
  .catch(function(err) {
    console.error('productApi::createCart error: ', err);
  });
 }

Now what i want is, i want to get cart code in addToCart API in response. I am trying to print cart code in console.log, but it's not printing anything and throwing exception.


Solution

  • First, you're trying to call a function that returns a Promise, which is asynchronous, and expect it to behave as if it was synchronous, which is not going to work:

    // this won't work
    const response = getCartCode(res)
    
    function getCartCode(res) {
      return createCart().then(function(result) {
        return {...}
      });
    }
    

    You'd have to use something like async/await if you want to be able to use getCartCode similarly to what you're doing right now, like so:

    app.post('/addToCart', function(req, res) {
      async function handleAddToCart() {
        // i suggest you use something like the `lodash.get`
        // function to safely access `conversation.memory.cart`
        // if one of these attributes is `undefined`, your `/addToCart`
        // controller will throw an error
        const cart = req.body.conversation.memory.cart
    
        // or, using `lodash.get`
        // const cart = _.get(req, 'body.conversation.memory.cart', null)
    
        if (!cart) {
          const response = await getCartCode().catch(err => err)
          // do whatever you need to do, or just end the response
          // and also make sure you check if `response` is an error
          res.status(200).json(response)
          return
        }
        // don't forget to handle the `else` case so that your
        // request is not hanging
        res.status(...).json(...)
      }
      handleAddToCart()
    })
    
    function getCartCode() {
      return createCart()
        .then(function(result) {
          return { conversation: { memory: { cart: result } } }
        })
        .catch(function(err) {
          console.error('productApi::createCart error:', err);
          throw err
        })
    }
    

    Second, don't pass res to the createCart function. Instead, get the data you need from the createCart function and call res.json inside the /addToCart controller.

    Here's how you have to handle this:

    app.post('/addToCart', function(req, res) {
      const cart = req.body.conversation.memory.cart
    
      if (!cart) {
        getCartCode()
          .then(function (result) {
            res.json(result)
          })    
          .catch(/* handle errors appropriately */)
         return;
      }
      // return whatever is appropriate in the `else` case
      res.status(...).json(...);
    })
    
    function getCartCode() {
      return createCart()
        .then(function(result) {
          return { conversation: { memory: { cart: result } } }
        })
        .catch(function(err) {
          console.error('productApi::createCart error:', err);
          throw err
        })
    }