0

I am currently trying to get a grip on async/await on javascript but having trouble understanding why 7 is not running at the end of everything. I know the culprit is calling the axios.get commands causing a delay but why are we not awaiting for them to finish to move on? I thought any await command pauses the event loop until the awaited function returns something.

Result:

0
1
before 2
1
before 2
7 - Writing to file ----------------------------------------------------------------------------------
(node:21116) UnhandledPromiseRejectionWarning: ReferenceError: result is not defined
    at processOrders (C:\Users\ReactFootwear\Desktop\Nodejs - Shopify Order System\app.js:30:5)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:21116) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:21116) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
2
3
2
3
4
5
6

My Code

const axios = require('axios').default;
const excel = require('exceljs');
const imageToBase64 = require('image-to-base64');
const fs = require('fs');


callShopifyOrdersApi();

// Get orders from shopify Api
async function callShopifyOrdersApi(){
  const url = 'https://shopifyurlhere.com/admin/api/2020-10/orders.json?created_at_min=2020-11-14'
  let responseData = await axios.get(url);
  processOrders(responseData.data.orders);

};


function processOrders(orders){
  console.log("Processing orders bitches");
  createWorkbook(orders).then(result => {

    console.log("7 - Writing to file ------------------------------------------------------------");

    var fileName = "Orders.xlsx";
    result.xlsx.writeFile(fileName).then(() => {
    });
  })
};


async function createWorkbook(orders){

    //Creating New Workbook 
    var workbook = new excel.Workbook();

    //Creating Sheet for that particular WorkBook
    var sheetName = 'Sheet1';
    var sheet = workbook.addWorksheet(sheetName);
    sheet.properties.defaultRowHeight = 200;

    //HEADER FORMAT
    sheet.columns = [ {key:"name", header:"name", width: 25}, {key: "address", header: "address"}];

    console.log("0")
    await compileRows(workbook, sheet, orders).then((workbook) => {return workbook})
  }


async function compileRows(workbook, sheet, orders){
  var rows = [];

  orders.forEach(async function (order) {

    order.line_items.forEach(async function (line_item, i) {
      var row = { name: order.customer.first_name , address: order.shipping_address.address1 }
      sheet.addRow(row);

    var img = await mainGetLineItemImg(line_item);
    
    console.log("3");

      if(i == 0){
 
        console.log("4");
        // add image to workbook by buffer
        const imageId2 = await workbook.addImage({
          buffer: fs.readFileSync('/Users/admin/Desktop/test.jpg'),
          extension: 'jpeg',
        });

        console.log("5");
        await sheet.addImage(imageId2, {
          tl: { col: 0, row: 3 },
          ext: { width: 180, height: 180 }
        });
        console.log("6");
      }
    });
  });
}


//GETTING IMAGE BASE 64
async function mainGetLineItemImg(line_item){
  console.log("1");
  var productId = line_item.product_id;
  var variantId = line_item.variant_id;
  console.log("before 2");

  const url = 'https://shopifyurlhere.com/admin/api/2020-10/variants/'+variantId+'.json';
  let responseData = await axios.get(url);
  var imageId = await responseData.data.variant.image_id;

  const url2 = 'https://shopifyurlhere.com/admin/api/2020-10/products/'+productId+'/images/'+imageId+'.json';
  let responseData2 = await axios.get(url2);
  var src = await responseData2.data.image.src;
  var base64code = await imageToBase64(src);


  console.log("2");
  return base64code;
}
Hasa
  • 3
  • 2
  • Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – crashmstr Nov 16 '20 at 16:03
  • You can't use `async/await` with `.forEach()`. Doesn't work. Use `for( ... of ...)` instead. – Jeremy Thille Nov 16 '20 at 16:05

1 Answers1

0

Looks like your problem is in the compileRows function. You are calling orders.forEach(), which runs immediately without awaiting any of the async stuff happening in its callback function. So compileRows completes almost immediately.

Instead, use for loops so that you can actually await the asynchronous operations:

async function compileRows(workbook, sheet, orders){
  for (const order of orders) {
    for (let i = 0; i < order.line_items.length; i += 1) {
      const line_item = order.line_items[i];

      var row = { name: order.customer.first_name , address: order.shipping_address.address1 }
      sheet.addRow(row);

      var img = await mainGetLineItemImg(line_item);
    
      console.log("3");

      if(i == 0){
 
        console.log("4");
        // add image to workbook by buffer
        const imageId2 = await workbook.addImage({
          buffer: fs.readFileSync('/Users/admin/Desktop/test.jpg'),
          extension: 'jpeg',
        });

        console.log("5");
        await sheet.addImage(imageId2, {
          tl: { col: 0, row: 3 },
          ext: { width: 180, height: 180 }
        });
        console.log("6");
      }
    }
  }
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169