1

Basically, I am using Node's FS module to read and write to a JSON file. Writing it works completely fine but for some reason reading it returns an empty string.

This file is called records.js

const dir = 'servers.json';

function write(content) {
    fs.writeFileSync(dir, content);
}

function read() {
    return fs.readFileSync(dir, 'utf-8');
}

var file = read(); //This is always empty

One thing tho: That script is a seperate module and is located in a subfolder to my main index.js. However if that was the cause, writing a file wouldn't work either.

Directory

servers.json
src/
    index.js
    util/
        records.js
9
  • welcome to nodejs event loop programming, you have to use promises to solve this problem. learn from this link developers.google.com/web/fundamentals/getting-started/primers/… Commented May 9, 2017 at 18:40
  • 2
    @InderRSingh they are using *Sync(), no need to use promises. Commented May 9, 2017 at 18:44
  • @robertklep i agree with you this is sync reading. But if you have code after readFileSync .. "which is not reading file & only displaying it". wouldn't that would go first, as per "Event driven programming" i understood which ever events comes first that would be execued. Correct me if i am wrong. Commented May 9, 2017 at 18:50
  • @InderRSingh *Sync() functions will block the event loop and wait before continuing the rest of the code. Commented May 9, 2017 at 18:51
  • 1
    What version of Node.JS are you using? The code you posted worked with my test setup. Commented May 9, 2017 at 18:54

2 Answers 2

2

Oh I am so dumb! The code I posted didn't have any mistakes actually. One thing I didn't include was that I fired fs.open before I read the file and I didn't know fs.open wipes a file, I just thought it would create it in case it didn't exist.

Sorry for wasting your time.

Sign up to request clarification or add additional context in comments.

Comments

0

First of all, every time that you read or write any file on the file system, always use an absolute path. When you use a relative path like you do here then it is relative to process.cwd() which may not be what you think.

In your case an absolute path to the file in your directory structure when accessed from records.js would be:

let path = path.join(__dirname, '..', '..', 'servers.json');

or:

let path = path.join(__dirname, '../../servers.json');

And instead of just:

var file = read();

you actually need to run:

write('something');

and then:

var file = read();

Also, since you're file to read seems to be JSON then you may want to read it as JSON. You can do it with require:

let object = require('../../file.json');

or you can read it and then parse it as JSON with JSON.parse() - but in that case make sure to put it inside of try/catch or otherwise your program will crash on invalid JSON.

Another thing is that since you said that it is a module that is required somewhere else, make sure to actually export the value that you want to be used somewhere else. For example:

var file = read();
module.exports = file;

and where you use it:

var data = require('records.js');

But note that when you have a JSON file then you can require it in other modules directly like this:

var data = require('../../servers.json');

with no need of having a module which has only one purpose of reading the JSON and exporting it to other modules.

Update

As Robert pointed out in the comments, it should be noted that require() or readFileSync() (or anythingSync) should only be used on the first tick of the event loop. I assumed that here the file is read once on startup and the results get exported for use by requiring modules. If the file is read during the lifetime of the program, e.g. in request controllers, event handlers, async functions etc. then only fs.readFile() or stream functions should be used.

4 Comments

If the file gets updated regularly, require() isn't ideal because it will read the file only once and cache its contents. Also, the OP states that "Writing it works completely fine", so I guess we should assume that something was already being written to the file :)
of course the .json has content before I read it. I was just surprised that writing worked, but reading didn't tho I used the exact same path. Also I didn't know you can require .json files. I'm gonna try that. I just have a question: If I do it via require, does it automatically update when the file's content changes?
@Emonadeo if you want to load that file more than once during the lifetime of your app, don't use require()
I 100% agree with comments by @robertklep above. I wouldn't recommend using require() (or readFileSync()` for that matter) anywhere else then on the first tick of the event loop. I assumed that here the file is read once on startup and exported. If the file is read during the lifetime of the program, e.g. in event handlers etc. then only fs.readFile() or stream functions should be used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.