Search code examples
node.jsexpressasynchronouspromisees6-promise

How can I give myself access to the resolved value of a previous promise in a chain?


I have a route in express where I want to perform a bunch of async operations, then add some data to the database if certain conditions are met. So far, it looks like this (index.js):

router.post('/distributor/:id/upload', upload.single('file'), function 
(err,req, res, next ) { 
  if (err) { 
    console.log(req);
    console.log(req.file);
    console.error(err);
    return res.sendStatus(500);
  }
  next()
}, function (req, res, next) {  
    // console.log(req.file);
    csv()
      .fromFile(req.file.path)
      .subscribe((json)=>{ 
        // console.log(json)
        return new Promise((resolve,reject)=>{
          let product = new Item(json.Title); 
          product.distributor_id = req.params.id 
          product.SKU = json.SKU 
          product.UPC = json.UPC 
          product.Price = json.Price 
          return resolve(product) 
    }).then((product) => {
      // console.log(product) 
      //async request to external API
      var productInfo = getPriceandASIN.getPriceandASIN(product.UPC) 
      return productInfo
    }).then((info) => {  
      console.log(info) 
      console.log(product) 
      //a bunch of other stuff I don't need to worry about yet
      // return res.end()
    })
  });
}) 

If I just console.log(info), I get the expected response, the result of calling the previous async function for each item in the collection. However, if I also try to console.log(product), the whole function breaks, and I just get the info for the first item in the collection (and not the product), and nothing else. What is causing this behavior? I think there is something I am fundamentally not understanding about resolving promises, but I cannot tell what from the docs.


Solution

  • There is no "product" variable to be dereferenced in the function that you're calling console.log(product) in, so the basics of programming apply: if you want to access a thing, make that thing accessible. In this case, make the previous handler return all the data you need. If that's one var, return one var. If it's multiple vars, return an object with all of them:

      ...
      }).then(product => {
        var productInfo = await getPriceandASIN.getPriceandASIN(product.UPC);
        return { product, productInfo };
      }).then(data => {  
        console.log(data.productInfo);
        console.log(data.product);
        // ...
      })
    });