0

I load a JSON from file as a string, try to parse it back to JSON and send as a response:

router.get('/todos', (req,res) =>{
    let todos = fs.readFile('todos.json', 'utf8',(err, data) =>{
        if (err) throw err

        res.send(JSON.parse(todos)) 
    })
})

my todos.json file:

{
    "todos": [
        {
            "id": 1,
            "text": "task number 1",
            "priority": 3,
            "done": false
        },
        {
            "id": 2,
            "text": "task number 2",
            "priority": 3,
            "done": false
        },
        {
            "id": 3,
            "text": "task number 3",
            "priority": 3,
            "done": false
        },
        {
            "id": 4,
            "text": "task number 4",
            "priority": 3,
            "done": false
        },
        {
            "id": 5,
            "text": "task number 5",
            "priority": 3,
            "done": false
        }
    ]
}

However I get this error:

undefined ^

SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse () at fs.readFile (/Users/mgonline/Desktop/programs/assessment/node-todo/routes/api/v1/todo.js:11:17) at FSReqWrap.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:53:3)

I don't know why but when I console.log this string fetched from file it seems like my program change it a bit by adding a commma after last object in array of collections:

{
    "id": 5,
    "text": "task number 5",
    "priority": 3,
    "done": false
},

Which supposedly rise this error. Should I rewrite my JSON different way in order to avoid collisions?

1
  • Try res.send(JSON.parse(data)) instead of res.send(JSON.parse(todos)) Commented Apr 5, 2020 at 14:06

3 Answers 3

1

The problem

You are using fs.readFile incorrectly. fs.readFile will return undefined because readFile is asynchronous. The contents of the file actually arrive in the data parameter of the callback that you provided.

To Fix

Remove let todos = entirely and just call fs.readFile (because you don't need the return value of fs.readFile).

Then call JSON.parse(data) instead of JSON.parse(todos) (because that's where your file's contents arrive).

Before

router.get('/todos', (req,res) =>{
    let todos = fs.readFile('todos.json', 'utf8',(err, data) =>{
        if (err) throw err

        res.send(JSON.parse(todos)) 
    })
})

After

router.get('/todos', (req,res) =>{
    fs.readFile('todos.json', 'utf8',(err, data) =>{
        if (err) throw err

        res.send(JSON.parse(data)) 
    })
})
Sign up to request clarification or add additional context in comments.

Comments

1

I guess,The editor automatically adds a comma when saving. try to change the setting of IDE to removing the comma from the array element when the json file is saved

Comments

1

You have not defined todos in your application, it is undefined hence you are getting error as,

As corrected by @Sebastian Kaczmarek, todos is holding return value of fs.readFile. As fs.readFile returns "undefined", you are getting error.

Use data which is the name of the argument in your script which holds the content of the required file.

router.get('/todos', (req, res) => {
  fs.readFile('todos.json', 'utf8', (err, data) => {
    if (err) throw err
    res.send(JSON.parse(data));
  })
})

2 Comments

Actually, he did define todos. He wrote let todos = fs.readFile(...) so it is defined but it's value is undefined. If it wasn't defined he would get ReferenceError
@SebastianKaczmarek- Oops! My bad, I will edit it. I totally missed that. Thanks!

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.