0

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)

Phlex
  • 28
  • 4
  • Duplicate: [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) –  Dec 21 '20 at 12:37
  • I think it does, you are probably logging to console before async file read finishes. – Dan Oswalt Dec 21 '20 at 12:40

1 Answers1

3

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.

Sebastian Kaczmarek
  • 8,120
  • 4
  • 20
  • 38
  • I tried using .readFileSync but then i dont get any output at all. Ill try to read up on those other things. – Phlex Dec 21 '20 at 12:45
  • Just a heads up, node.js now has promise based FS module, to save you having to promisify. https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_promises_api – Keith Dec 21 '20 at 12:47
  • https://stackoverflow.com/a/45191380/14048292 - This comment made me realize .readFileSync ignores callback, after adjusting my code i managed to get it work. Main post updated. – Phlex Dec 21 '20 at 12:53