0

I am trying to load json data for a small project of mine, but when I run loadDefs (the function meant to save the data to the Game class) it seems to run fs.readFile before checking wether file_data has been modified.

loadDefs(file_path:any)
    {
        let file_data:string = '';
        fs.readFile(file_path, 'utf8', (err, data:string) => {
            if (err) {
              console.error(err);
              return;
            }
            file_data = data;
            console.log(file_data);
        });
        if (file_data == '')
        {
            console.log("Data not loaded.");
            return;
        }

        const loading_defs:Array<any> = JSON.parse(file_data);
        console.log(loading_defs);
        for (let index = 0; index < loading_defs.length; index++) {
            const def = loading_defs[index];
            if (def["type"] == "DefTypeDef")
            {
                this.defs[def["uuid"]] = {};
            }
            this.defs[def["type"]][def["uuid"]] = def;
        }
    }

The part that runs the function

    let g = new Game();
    g.loadDefs("./Defs/defTypes.json")

This was the output (the lower is the content of my "./Defs/defTypes.json" file):

Data not loaded.
[
    {
        "type": "DefTypeDef",
        "uuid": "WorldObjectDef"
    },
    {
        "type": "DefTypeDef",
        "uuid": "NAME"
    }
]

I expected this code to log the contents of the json file and load them in the way specified.

While troubleshooting I tried reading the file outside of the function and passing it later, but encountered the same problem, I've tried using another json file with different content but neither worked. I do not know how to get my code to execute in the expected order.

MisterZig
  • 3
  • 2

1 Answers1

0

Take a look at the fs.readFile() documentation here. Basically it is an async function, so the content of the file will only be available (in your example) in the callback passed as the 3rd argument. You can modify the code as follows:

loadDefs(file_path:any)
{
    let file_data:string = '';
    fs.readFile(file_path, 'utf8', (err, data:string) => {
        if (err) {
          console.error(err);
          return;
        }
        file_data = data;
        console.log(file_data);

        if (file_data == '')
        {
            console.log("Data not loaded.");
            return;
        }

        // do what else needs to be done with the file content
    });
}

If you're unfamiliar with this concept, I highly recommend you to read a little about asynchronous programming, as it's a must for web programming. A nice guide is here, but there are many others.

Mar
  • 167
  • 1
  • 8
  • 1
    I was able to replace readFile with readFileSync which is not asynchronous, which solved the problem – MisterZig Jan 14 '23 at 09:43
  • In general it's best to use asynchronous functions for I/O operations, like reading/writing to files, or for fetching stuff from web APIs. The reason is that these operations may take a long time, and you don't want (most of the time at least) to have the user interface blocked while the operation is loading. I still suggest, when you have time, to read a little about asynchronous code in JavaScript :) – Mar Jan 14 '23 at 11:51