3

Im trying to make a weather app and I'm using a weather API to get the information but this error shows up when I'm trying to parse the JSON data: SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) at IncomingMessage.<anonymous> edit: I need to get the lat and lon values from an https request. I tried returning it but it will still say lon and lat is undefined.

second edit: If I input the values of lon and lat It will parse the data and send back the JSON but I need the values of lon and lat from the locaionIQ API on the https request. How do I get those values? here is the code:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const https = require('https');
const { static, response } = require('express');
require('dotenv').config();


app.use(bodyParser.urlencoded({extended:true}));
app.use(express.static('public'))

app.listen(3000, ()=>{
  console.log("server is running on port 3000")
})

app.get('/', (req,res)=>{
  res.sendFile(__dirname+'/index.html')
})

app.post('/', (req,res)=>{
  
  let apiKeyLocationIQ = process.env.API_KEY_LOCATIONIQ;
  let apiKeyWeather = process.env.API_KEY_WEATHER;
  let cityLocationIQ = req.body.citySearch;
  let urlLocationIQ = "https://api.locationiq.com/v1/search.php?format=JSON&key="+apiKeyLocationIQ+"&q="+cityLocationIQ+"&limit=1";
  https.get(urlLocationIQ, function(response){
    response.on("data",function(data){
      let locationIQ = JSON.parse(data);
      const lat= locationIQ[0].lat;
      const lon= locationIQ[0].lon;
      const cityName = locationIQ[0].display_name;
    })
  })

  let urlWeather = 'https://api.openweathermap.org/data/2.5/onecall?&lat='+lat+'&lon='+lon+'&exclude=alerts,minutely&units=metric&appid='+apiKeyWeather+'&lang=en&cnt=7';
  https.get(urlWeather, function(response){
    response.on("data",function(data){
      let weatherData = JSON.parse(data);
      console.log(weatherData);
      
    })
  })
  
})
Cloyd Abad
  • 617
  • 8
  • 16
  • Does this answer your question? [Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse ()](https://stackoverflow.com/questions/51118396/uncaught-syntaxerror-unexpected-end-of-json-input-at-json-parse-anonymous) – Ace Jan 07 '21 at 01:46
  • Log if you're getting valid JSON string or not here. `let locationIQ = JSON.parse(data);`. `data` might have already `parsed`. – Naren Jan 07 '21 at 02:10
  • Im getting JSON String if Input the lon and lat values on the API URL. but when I try to use the value from the other api it won't work. I tried returning the value but still the same – Cloyd Abad Jan 07 '21 at 02:13

2 Answers2

3

Under Node, HTTP/HTTPS request data can arrive in multiple chunks which need to be amalgamated before parsing the resultant JSON string.

Essentially JSON parsing needs to be performed in an on("end", callback), not in an on("data", callback), or risk incomplete JSON text.

Node documentation has an excellent working example for getting JSON data under http.get(options[, callback]). This does not appear to be duplicated in the HTTPS section of documentation due to similarities of the HTTP and HTTPS APIs.

traktor
  • 17,588
  • 4
  • 32
  • 53
  • im sorry im very new to programming but may I know what I should do? what should I change? I tried changing the response.on to 'end' but its still the same – Cloyd Abad Jan 07 '21 at 02:34
  • 1
    @CloydAbad Adapt the linked example to suite your needs in terms of getting JSON data. For example you can't omit the `on(data, callcack)` processing to concatenate arriving data. Waiting for both API calls to complete before responding to the request will also be necessary. This may require nested callback requests or promisifying `https.get` using (`util.promisify(original)`)[https://nodejs.org/docs/latest/api/https.html#https_https_get_options_callback] or similar. The `await` operator is often useful when it comes to processing results. – traktor Jan 07 '21 at 04:05
  • 1
    hey man sorry it took so long for me to reply hehe, anyway I learned asyn await last week and I finall understand what youre saying, thank you! – Cloyd Abad Feb 11 '21 at 01:42
0

Https response data are collected in small chunks, so when its collecting data ("on"), we should append the data(string) in variable (starting with empty string [here let chunks="";])

When all the chunks of data are collected ("end"), then we should finally parse the string(API data) into JSON format.

https.get(apiLink, function (response) { 

        let chunks="";
        response.on("data", function (chunk) {
            chunks+=chunk;
        });
        response.on("end", function(){
            // console.log("API Data recieved");

            let defaultCovidData = JSON.parse(chunks);
            // code after parse string into JSON format
        });

});
General Grievance
  • 4,555
  • 31
  • 31
  • 45