1

I am declaring an array list_of_blogposts and then I am opening a file to pull data from it, and in it, I am declaring an object blogpost_object in which I am entering key-value pairs. When I console log it inside the opened file code block it does console log properly, but outside it, it shows empty, like in the last line it doesn't work. Can anybody mention whats the reason and solution for it? Thanks, the code is below

const list_of_blogposts = [];

new XLSX()
  .extract("./all_blogposts.xlsx", {
    ignore_header: 2,
    include_empty_rows: false,
    sheet_name: "all_blogposts"
  })
  .on("row", function(row) {
    var blogpost_object = {};
    blogpost_object["title"] = row[2];
    list_of_blogposts.push(blogpost_object);

    console.log(list_of_blogposts);
  });

console.log(list_of_blogposts);
Raghul SK
  • 1,256
  • 5
  • 22
  • 30

2 Answers2

2

This is because the function(row) {... is a callback function thus it is executed asynchronously. So the flow of execution will be like

  1. execute .on()
  2. call the function in callback function(row) {...
  3. execute the console.log outside the function
  4. finally, the execution of the callback function

Thus, the console.log you have outside the function is executed before the callback function is called so it returns an empty array. The console.log within the function returns the array after the values are pushed.

So what you can do to solve this problem is do whatever you want to do with the array of values within the callback function.

const doAction = (list) => {
   //Do whatever you want
}

const list_of_blogposts = [];

new XLSX()
  .extract("./all_blogposts.xlsx", {
    ignore_header: 2,
    include_empty_rows: false,
    sheet_name: "all_blogposts"
  })
  .on("row", function(row) {
    var blogpost_object = {};
    blogpost_object["title"] = row[2];
    list_of_blogposts.push(blogpost_object);

    console.log(list_of_blogposts);
    doAction(list_of_blogposts)
  });

console.log(list_of_blogposts);

Hope it helped!!!

theWellHopeErr
  • 1,856
  • 7
  • 22
  • couldnt understand your solution, but your execution flow makes sense probably. even in the code you wrote will show empty console log from outside – Arsalan Ahmad Ishaq Jul 04 '20 at 06:47
  • 1
    Yeah, it shows it as an empty log because the array is empty. You can read about asynchronous execution [here] (https://stackoverflow.com/a/748189/8826642). What my solution suggests is to perform whatever action you would like to do within the callback function as the array is being pushed one by one. Or if you require the full array you can checkout await/async. – theWellHopeErr Jul 04 '20 at 07:25
1

You can use the .on('end' method for actions you need to perform after all the rows have been read. Similarly, you can use .on('error' for handling error scenarios.

The code can be

const list_of_blogposts = [];
new XLSX()
  .extract("./all_blogposts.xlsx", {
    ignore_header: 2,
    include_empty_rows: false,
    sheet_name: "all_blogposts"
  })
  .on("row", function(row) {
    var blogpost_object = {};
    blogpost_object["title"] = row[2];
    list_of_blogposts.push(blogpost_object);

    console.log(list_of_blogposts);
  }).on('end', function (err) {
    console.log(list_of_blogposts);
    your_method(); // you can perform anything you want after all rows are read
  });
Harsha Venkataramu
  • 2,887
  • 1
  • 34
  • 58