'SyntaxError: Unexpected end of JSON input - why is that?

This is the code I have written using express and node.js

    const express = require("express");
    const https = require("https");
    const app = express();
    
    app.get("/", function(req, res) {
    
        // Url to my api key
         const url = "https://api.spoonacular.com/recipes/random?apiKey=...&number=1";
    
         https.get(url, function(response) {
    
              response.on("data", function (data) {
                   console.log(JSON.parse(data));
                   // const theRecipe = JSON.parse(data);
                   console.log(data);
              });
    
         });
    
         res.send("The server is up and running");
    });
    
    app.listen(3000, function () {
         console.log("Server started at port 3000");
    });

When I refresh my webpage on localhost, on console I get the following error:

quote SyntaxError: Unexpected end of JSON input at JSON.parse () at IncomingMessage. (C:\Users\ArunBohra\Desktop\FoodRecipes\app.js:12:33) quote

Can anyone find what is the problem with my code.



Solution 1:[1]

The data event fires when a chunk of data from the response has arrived. You are trying to parse the first chunk as if it were the complete JSON text.

You need to collect the pieces from each data event but wait until the end event fires before joining them together into the complete string of JSON that you can parse.

There is an example of fetching and parsing JSON in the documentation.

You might want to look at modules like axios and node-fetch which take care of that (and the JSON parsing) for you while providing modern Promise based APIs.

If you have a new enough version of Node, you can use the native Fetch API.

Solution 2:[2]

If you use a package like node-fetch you can get the whole thing in one go instead of what you have now which is chunking the data

const fetch = require('node-fetch');
const url = "https://api.spoonacular.com/recipes/random?apiKey=...&number=1";
fetch(url)
  .then(response => response.json())
  .then(data => console.log(data));

Solution 3:[3]

In addition to other answers, you can do it without another package.

https.get(url, function (response) {
    let result = "";
    response.on("data", function (data) {
        result += chunk;
    });
    res.on('end', () => {
        // now you have the combined result
        console.log(result);
    });
}); 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 mplungjan
Solution 3 lastr2d2