简体   繁体   中英

How to assign an object returned by an async function to a variable

I have a function that scrapes a data from a website. THe function is this:

  const getSharesInfo = async () => {
      try {
        const { data } = await axios.get(url);
        const $ = cheerio.load(data);
        const elmSelector =
          "#ctl00_ContentPlaceHolder1_LiveTrading > table > tbody > tr";
        const keys = [
          "Name",
          "LTP",
          "% Change",
          "Open",
          "High",
          "Low",
          "Qty",
          "Close Price",
        ];
        $(elmSelector).each((parentIdx, parentElm) => {
          let keyIdx = 0;
          const sharesObj = {};
          $(parentElm)
            .children()
            .each((childIdx, childElm) => {
              const tdValue = $(childElm).text();
              if (tdValue) {
                sharesObj[keys[keyIdx]] = tdValue;
                keyIdx++;
              }
            });
          console.log(sharesObj);
          return sharesObj;
        });
      } catch (err) {
        console.error(err);
      }
    };

It makes an object from the data scraped. Then when I run the function it console log the shareObj and output is like this:

{
  Name: 'USLB',
  LTP: '890.00',
  '% Change': '0.79',
  Open: '890.00',
  High: '888.10',
  Low: '888.10',
  Qty: '24'
}
{
  Name: 'VLBS',
  LTP: '849.00',
  '% Change': '0',
  Open: '850.00',
  High: '833.00',
  Low: '834.00',
  Qty: '285'
}
{
  Name: 'WNLB',
  LTP: '927.30',
  '% Change': '-4.4',
  Open: '965.00',
  High: '927.30',
  Low: '965.00',
  Qty: '270'
}

I want to catch it and pass it to the home route. I have setup router like this.

app.get("/", async (req, res) => {
  const shares = await getSharesInfo();
  res.render("home", { shares });
});

But when I console log shares I get nothing. No errors no data nothing. It just prints some empty spaces. How can I solve this??

Move the const sharesObj = {} declaration outside of the call to .each (= move it up 3 lines) and move the line return sharesObj; out of the .each loop, too (eg: move it down two lines).

As of now you create the constant binding inside .each and then return it inside the .each callback, not in getSharesInfo .

Example:

  const getSharesInfo = async () => {
  try {
    const { data } = await axios.get(url);
    const $ = cheerio.load(data);
    const elmSelector =
      "#ctl00_ContentPlaceHolder1_LiveTrading > table > tbody > tr";
    const keys = [
      "Name",
      "LTP",
      "% Change",
      "Open",
      "High",
      "Low",
      "Qty",
      "Close Price",
    ];
    const sharesObj = {}; // <-- new position
    $(elmSelector).each((parentIdx, parentElm) => {
      let keyIdx = 0;
      //const sharesObj = {}; <-- old position
      $(parentElm)
        .children()
        .each((childIdx, childElm) => {
          const tdValue = $(childElm).text();
          if (tdValue) {
            sharesObj[keys[keyIdx]] = tdValue;
            keyIdx++;
          }
        });
      console.log(sharesObj);
      //return sharesObj; <-- old position
    });
    return sharesObj; // <-- new position
  } catch (err) {
    console.error(err);
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM