Skip to content

Node.js – Cannot append global variable when using fs

Im trying to read multiple xml files and parse data from them and i managed to do that but now new problem appeared.

allData variable is never changed, no matter what i do. What am i supposed to do here?

I dont know what to do or what to try, this is my first time working with files and im honestly surprised ive managed to come this far.

var parseString = require('xml2js').parseString;

var fs = require('fs')
var allData = {
    store: []
}

function readFiles(__dirname, onFileContent, onError) {


    fs.readdir(__dirname + '\parse\', function (err, filenames) {
            if (err) {
                return;
            }


            filenames.forEach(function (filename) {


                    console.log(filename)
                    fs.readFile(__dirname + '\parse\' + filename, 'utf-8', function (err, content) {
                            if (err) {
                                console.log(err)
                                return;
                            }
                            parseString(content, function (err, result) {

                                let tempObj = {}

                                let data = result.storeD[0]
                                

                                if (data.name) {
                                    tempObj['name'] = data.name[0];
                                }

                                if (data.price) {

                                    tempObj['price'] = data.price[0];
                                }


                                //more of the same type of code

                                console.log(tempObj)
                                //output: { name: 'Data1', price: '1000' }

                                allData.store.push(tempObj)

                            })


                        })

                        

                    })


            });

            console.log("All data: ",allData)
            //Outputs once at the begining 
            //output: All data:  { store: [] }


    }
    

readFiles(__dirname)

SOLVED

adjusted code to use.readFileSync()(removed callback function) and now it works.

var parseString = require('xml2js').parseString;

var fs = require('fs')
var allData = {
    store: []
}

function readFiles(__dirname, onFileContent, onError) {


    fs.readdir(__dirname + '\parse\', function (err, filenames) {
            if (err) {
                return;
            }


            filenames.forEach(function (filename) {


                    console.log(filename)
                    let file = fs.readFileSync(__dirname + '\parse\' + filename, 'utf-8')
                            parseString(file, function (err, result) {

                                let tempObj = {}

                                let data = result.storeD[0]
                                

                                if (data.name) {
                                    tempObj['name'] = data.name[0];
                                }

                                if (data.price) {

                                    tempObj['price'] = data.price[0];
                                }


                                //more of the same type of code

                                console.log(tempObj)
                                //output: { name: 'Data1', price: '1000' }

                                allData.store.push(tempObj)

                            })


                        

                        

                    })

                    console.log("All data: ",allData)
            });

            
            //Outputs once at the begining 
            //output: All data:  { store: [] }


    }
    

readFiles(__dirname)

Answer

The .readdir() and .readFile() methods are async, so in fact the console.log() is executed before all of the readFile operations.

In order to access the allData variable after these operations are complete, you have to either make them sync using .readFileSync() instead or you need to promisify the .readFile() method and wait for all of the promises to resolve.