1

I'm trying to push info into array, but the array comes out as empty. What am I doing wrong?

function fixItems(items){
    var fixeditems = [];
    fs.readFile('prices.json', 'utf8', function(err, data){
        if(err){}
        var jason = JSON.parse(data);
        for(var k = 0; k < jason.prices.length; k++){
            for(var i = 0; i < items.itemsToReceive.length; i++){
                fixeditems.push({
                    name: items.itemsToReceive[i].market_hash_name,
                    classid: items.itemsToReceive[i].classid
                });
            }
        }
    });
    return fixeditems;
}
NotBad4U
  • 1,299
  • 1
  • 12
  • 20
  • @JJJ If I may ask, how is it asynchronous call? – James Aniszt Mar 11 '17 at 21:11
  • 2
    The push itself seems fine. Your problem is probably the loops. Either `json.prices` is empty or `items.itemsToReceive` is.. – Chris Mar 11 '17 at 21:11
  • Nope, I checked with console.log – James Aniszt Mar 11 '17 at 21:12
  • Both return value to me. – James Aniszt Mar 11 '17 at 21:12
  • 3
    `fs.readFile` is an asynchronous method. – JJJ Mar 11 '17 at 21:15
  • 2
    I have a strong feeling that you should have used [`fs.readFileSync`](https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options). The very fact that `fs.readFile` expects a function of (error, data) as the last argument is a sign it's asynchronous. – rishat Mar 11 '17 at 21:16
  • 1
    Switch to [fs.readFileSync()](https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options) – NotBad4U Mar 11 '17 at 21:16
  • Thanks to them who gave a suggestion to switch to `fs.readFileSync` – James Aniszt Mar 11 '17 at 21:20
  • As a general rule, switching to `fs.readFileSync` is **not** the best solution. Node is asynchronous for a reason. If you use synchronous reads, the entire server will block until the reading is complete. –  Mar 12 '17 at 05:09
  • *How is it asynchronous call?* It is an asynchronous call because `fs.readFile` is by nature asynchronous. –  Mar 12 '17 at 05:10

1 Answers1

0

It's an async call, so your variable is returned before it is filled up. Actually you could go like this, if being async is not a priority:

function fixItems(items){ 
    let fixeditems = [];
    let data = fs.readFileSync('prices.json', 'utf8')
    let jason = JSON.parse(data); 
    for(var k = 0; k < jason.prices.length; k++){ 
        for(var i = 0; i < items.itemsToReceive.length; i++){ 
            fixeditems.push({ 
                name: items.itemsToReceive[i].market_hash_name,
                 classid: items.itemsToReceive[i].classid 
             }); 
         }
    }
}

Otherwise you can wrap everything in a Promise or use libraries such as Async to perform these kind of tasks.

Phugo
  • 390
  • 1
  • 10