Garrowolf
Garrowolf

Reputation: 5

Javascript/Node/JSON question, why is this not working?

I thought I understood what I was doing until this wasn't going in order. I am running this through Node, not through a browser.

It goes to the prompt at the end of the while loop first. I don't know why.

const fs = require('fs');
const prompt = require('prompt-sync')();

function jsonReader(filepath, cb){
    fs.readFile(filepath, 'utf-8', (err, fileData) => {
        if (err) { return cb && cb(err); }
        try {
            const object = JSON.parse(fileData);
            console.log(object);
            return cb && cb(null, object);
        } catch (err) {
            return cs && cb(err);
        }
    });
}

var exit = 0;

do {

    jsonReader('./customer.json', (err, customer) => {
    if (err) {
        console.log('Error reading file:',err)
        return
    }
    
    //customer.order_count +=1
    
    const note = prompt("Enter a note for the JSON file: ");
    customer.note = note;
    
    fs.writeFile('./customer.json', JSON.stringify(customer, null, 2), (err) =>{
        if (err) {
            console.log('Error writing file:',err)
        } else {
            console.log('File updated');
        }
            
    })
})

exit = prompt("Do you want to exit?");

} while (exit != 'y'); 

Upvotes: 0

Views: 120

Answers (2)

slebetman
slebetman

Reputation: 113896

There are several things wrong with your code. The prompt problem you notice is just the beginning.

The way your code executes is like this:

// happens now

do {

    // happens now
    // ...

    jsonReader('./customer.json', (err, customer) => {
        // happens after readFile
    
        fs.writeFile('./customer.json', JSON.stringify(customer, null, 2), (err) =>{
            // happens after writeFile
            // ...
        })

        // happens after readFile
        // ...
    })

    // happens now
    exit = prompt("Do you want to exit?");

} while (exit != 'y');

// happens now

The time sequence is as follows:

1. Things that happens now
2. Things that happens after readFile
3. Things that happens after writeFile

It is obvious that you are outputting the prompt before either readFile or writeFile.

However there is another problem. You have an infinite while loop. In node.js and in fact in the browser I/O only happens when there is no javascript to execute - in other words it happens when the interpreter is idle. You are preventing the script from reaching the end of script with the while loop therefore the interpreter is never idle.

For your script what will happen after you fix the prompt issue is:

1. Things that happens now
2. loop into things that happens now
3. loop into things that happens now
4. loop into things that happens now
5. loop into things that happens now
..
∞. loop into things that happens now

Thus the readFile and writeFile never executes. You need to replace the while loop either with a recursive asynchronous call or using setTimeout() or setInterval() or use a while loop with async/await.

Here's an implementation with miniminal changes to your code:

function doIt () { // <----------- replace the do..while loop

    // ...

    jsonReader('./customer.json', (err, customer) => {
        // ...
    
        fs.writeFile('./customer.json', JSON.stringify(customer, null, 2), (err) =>{
            // ...

            var exit = prompt("Do you want to exit?");
            if (exit !== 'y') {
                doIt(); // <-------------- repeat the process again
            }
        })
    })
}

doIt(); // <--------- don't forget to begin the whole thing

This is admittedly not as easy to read as using async/await but I leave that implementation as homework. Besides, it requires much more changes to your existing code.

Upvotes: 1

Unmitigated
Unmitigated

Reputation: 89234

It is because fs.readFile is asynchronous, so your second prompt is executing before fs.readFile has finished. You may want to use async functions and await or put the prompt at the end of the callback for jsonReader.

Upvotes: 1

Related Questions