25

I'm trying so get the number of items in the array inside this piece

JSON

{
  "collection" : [
    {
      "item": "apple"
    },
    {
      "item": "banana"
    }]
}

Using the following JS (NodeJS): Updated with answers from user 'elssar'

var data = JSON.parse(fs.readFileSync(filePath));
console.log(data.collection.length);

Expected result: 2

Without specifying the encoding data will be a buffer instead of string (thanks to user nils). JSON.parse should work for both. Now I'm getting an error Unexpected token ? at Object.parse (native). Any idea how to fix this? (using Node 5.2.0)

Matthijs van Hest
  • 769
  • 1
  • 6
  • 12
  • Possible duplicate of [Why does Node.js' fs.readFile() return a buffer instead of string?](http://stackoverflow.com/questions/6456864/why-does-node-js-fs-readfile-return-a-buffer-instead-of-string) – nils Jan 14 '16 at 12:14
  • @nils not really a duplicate, as setting the content type would only give the op a string, which does not solve his problem – elssar Jan 14 '16 at 12:17
  • Duplicate : http://stackoverflow.com/questions/10011011/using-node-js-how-do-i-read-a-json-object-into-server-memory – NiRUS Jan 14 '16 at 12:22

1 Answers1

23

You need to parse the content of the file to JSON.

fs.readFile(filePath, function (error, content) {
    var data = JSON.parse(content);
    console.log(data.collection.length);
});

Or

var data = JSON.parse(fs.readFileSync(filePath));

Alternatively, you could just require json files (the file extension needs to be .json)

var data = require(filePath);
console.log(data.collection.length);
elssar
  • 5,651
  • 7
  • 46
  • 71
  • Your first snippet will probably not work, as `data` is undefined, and even if you used `content`, it would be a buffer. – nils Jan 14 '16 at 12:23
  • @nils oops. fixed :) – elssar Jan 14 '16 at 12:24
  • Spotted that as well. Still it doesn't work for me. It still says that `data` is undefined. The alternative you gave me seems to work. But why is my Intelli saying it IS an built-in function but also states: `use of an implicitly declared global variable 'require'` ?? – Matthijs van Hest Jan 14 '16 at 12:28
  • You still haven't set an encoding... look at my duplicate link. – nils Jan 14 '16 at 12:29
  • @nils not required. `JSON.parse` works without setting the encoding – elssar Jan 14 '16 at 12:34
  • @MatthijsvanHest Just tested the snippet it works. Are your trying to use `data` outside of the fs callback function scope? Since the variable data is local to that scope, it is not available outside. As for your IDEs warning, no clue, don't use it. – elssar Jan 14 '16 at 12:36
  • the encoding is not required but does make a difference in returning a buffer or a string. @elssar , I can;t get it to work. No I'm smart enough to know about scopes, so I'm just using it inside the scope of the fs callback function :). – Matthijs van Hest Jan 14 '16 at 12:38
  • Oh, nice to know that JSON.parse works with the buffer as well. Just one thing though, you can't access `data` in the `console.log` outside, because `fs.readFile` is an async call (thus called after all currently running code has finished). – nils Jan 14 '16 at 12:39
  • @nils doh! true, I had forgotten about that. I shall blame the 2 hours of sleep I got last night for this errors :) – elssar Jan 14 '16 at 12:40
  • It says `unexpected token ? at Object.parse (native)` using `var data = JSON.parse(fs.readFileSync(filePath));` any idea? – Matthijs van Hest Jan 14 '16 at 12:53
  • @MatthijsvanHest what version of node are you using? – elssar Jan 14 '16 at 12:57
  • @elssar version 5.2.0 – Matthijs van Hest Jan 14 '16 at 12:58
  • It could be a problem with your file. While I was testing I can across a file that gave me a similar error – elssar Jan 14 '16 at 13:03
  • Try `JSON.parse(fs.readFileSync(filePath).toString())`, or `JSON.parse(fs.readFileSync(filePath, 'utf-8'))` – elssar Jan 14 '16 at 13:05