91

I'm using a simple Node.js to pull information from a valid jsonfile (checked with JSLint), but the code i'm using doesn't return the expected value:

        squadJSON = JSON.parse(fs.readFileSync('./squads/squad' + whichSquad + '.json'));    

and it returns:

{ type: 'Buffer', data: 
[ 123,
 10,
 32,
 32,
 34,
 97,
 99,
 ... 548 more items ] }

Any reason as to why this happens?

2
  • What's the expected value? Commented Feb 16, 2018 at 0:28
  • 1
    No. JSON.parse does never return a buffer. Commented Feb 16, 2018 at 0:52

2 Answers 2

196

fs.readFileSync() returns a Buffer if you don't specify an encoding.

https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options

So, tell fs.readFileSync() what encoding to use:

squadJSON = JSON.parse(fs.readFileSync('./squads/squad' + whichSquad + '.json', 'utf8')); 
Sign up to request clarification or add additional context in comments.

1 Comment

Yup! Passing a value to the 2nd parameter will do the trick like so: fs.readFileSync('/path/to/file.json', 'utf8'). Thank you so much.
12

The "why" has been answered by Sidney, but a better "what to do" would be to use require(), which supports parsing valid JSON files synchronously and returning the result as an object:

squadJSON = require('./squads/squad' + whichSquad + '.json');

or even nicer, using an ES6 template literal:

squadJSON = require(`./squads/squad${whichSquad}.json`);

One notable difference using require() is that it resolves relative paths from __dirname, which is the directory path of the current module, whereas fs methods resolve relative paths using process.cwd(), or "current working directory". It is the directory within a shell session from which the main module of the program is executed by node.

Hopefully the examples below demonstrate how their relative path resolution differs:

To make require(...) behave like JSON.parse(fs.readFileSync(..., 'utf8')):

const { resolve } = require('path');

function readFileSyncJson (path) {
  return require(resolve(process.cwd(), path));
}

And to make JSON.parse(fs.readFileSync(..., 'utf8')) behave like require(...):

const { resolve } = require('path');

function requireJson (path) {
  return JSON.parse(fs.readFileSync(resolve(__dirname, path), 'utf8'));
}

5 Comments

Very true, require is much more convenient for reading JSON files. Also, require always resolves relative to the file it's called in, whereas I believe fs.readFileSync resolves based the current working directory (unless you specifically resolve using __dirname).
Sorry, but it returns the exact same thing for me, whether i use Require or specify the encoding... @sidney
@ConradScherb that can often be the case, which means that the module require() is called from is in the same directory as (or is) the file you invoked using node.
@PatrickRoberts so in that case what would be the solution to that?
@ConradScherb I added examples to hopefully clarify their differences. There's no problem in the first place, the information is just there to make you aware of nuances.

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.