JavaScript Node.js Basics Create a Command Line Weather Application Parsing Data and Printing - Solution

cannot read property 'city' of undefined

app.js file:

const weather = require('./weather.js');

const query = process.argv.slice(2).join("_").replace(' ', '_');
weather.get(query);

weather.js file:

const https = require('https');
const http = require('http');
const api = require('./api.json');

// print error messages
function printError(error) {
  console.error(error.message);
}

function printWeather(weather) {
  const message = `Current temperature in ${weather.display_location.city} is ${weather.current_observation.temp_f}F`;
  console.log(message);
}

function get(query) {
  try {
    const request =
          https.get(`https://api.wunderground.com/api/${api.key}/geolookup/conditions/q/${query}.json`,
                    response => {
                            if (response.statusCode === 200 ) {  
                              let body = "";
                              // Read the data
                              response.on('data', chunk => {
                                body += chunk.toString();
                              });

                              response.on('end', () => {
                                try {
                                  // Parse the data
                                  const weather = JSON.parse(body);    
                                  printWeather(weather);
                                  // Print the data
                                } catch (error) {
                                  printError(error);
                                }                   
                              });
                            } else {
                              const message = `There was an error getting the weather for (${http.STATUS_CODES[response.statusCode]})`
                              const statusCodeError = new Error(message);
                              printError(statusCodeError)
                            }                          
                     });
        request.on('error', error => console.error(`Problem with request: ${error.message}`));
  } catch (error) {
    printError(error);
  }
}

module.exports.get = get; 
Steven Parker
Steven Parker
163,562 Points

If you share your code by making a snapshot of the workspace (and provide the link to it) it makes it possible to easily test it and analyze the issue.

5 Answers

Steven Parker
Steven Parker
163,562 Points

There are several possible causes for this issue:

  • the API key might be invalid
  • the query (based on supplied command line arguments) might be invalid
  • the API might be returning a different format than expected

I suggest adding "console.log" statements to show both the outgoing query string and the response body that is returned. This information should help to identify both the type of problem and the actual cause.

If you still need help, please start a new question, and include a snapshot of your workspace (with your actual key redacted), and indicate exactly how you are invoking the app (showing the arguments you supply on the command line).

Jesse Thompson
Jesse Thompson
10,682 Points

Im having the same exact issue.

edit: ok changing the https.get request url to https://api.wunderground.com/api/${api.key}/geolookup/conditions/q/${query}.json fixed it for me but im not sure what the issue is in your case.

Steven Parker
Steven Parker
163,562 Points

That appears to be exactly the same as shown in the original code. Am I missing something?

Mary Paul
Mary Paul
13,791 Points

I'm having the same problem.

Adam Lyles Kauffman
Adam Lyles Kauffman
11,325 Points

the api service provided in your code no longer offers free api keys to the public. there is a new service openweathermap.org which will give you a key after registering for an account. use the updated code provided in the teachers notes for both files, also update the key value in your api.json. then to answer your original inquiry, after parsing the data use the following code for the message to access the property values of the new object from the new weather api service. const msg = Current tempature in ${weather.sys.name} is ${weather.main.temp} with the max tempature being ${weather.main.temp_max} and the minimum being ${weather.main.temp_min};