Wanderlust Project - Uncaught (in promise) TypeError: Cannot read property '0' of undefined

Wanderlust project link: [https://www.codecademy.com/courses/intermediate-javascript-requests/projects/wanderlust?course_redirect=introduction-to-javascript]
(https://www.codecademy.com/courses/intermediate-javascript-requests/projects/wanderlust?course_redirect=introduction-to-javascript)

I have the project completed for the most part but cant get the Weather portion to populate. In the console, i’m getting the following error:

image

When i view the main.js in the browser source tab, it flags line 77 as the issue. Problem is, i dont understand what the issue is.

image

Any help/guidance would be much appreciated. see below for my full code.

// Foursquare API Info
const clientId = '51TSTKPB5402ROQV1DD4MY4N2JFHCVR4YGEL5YNCMFUIL0UJ';
const clientSecret = 'HDAY00UNO23GZUZTDJORG5HOGWQ4ZHSIP5OMBZUPR1KAO4XJ';
const url = 'https://api.foursquare.com/v2/venues/explore?near=';

// APIXU Info
const apiKey = '360b89696c924f19a4c30238181109';
const forecastUrl = 'https://api.apixu.com/v1/forecast.json?key=';

// Page Elements
const $input = $('#city');
const $submit = $('#button');
const $destination = $('#destination');
const $container = $('.container');
const $venueDivs = [$("#venue1"), $("#venue2"), $("#venue3"), $("#venue4")];
const $weatherDivs = [$("#weather1"), $("#weather2"), $("#weather3"), $("#weather4")];
const weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

// Add AJAX functions here:
const getVenues = async () => {
const city = $input.val();
const urlToFetch = url + city + '&limit=10&client_id=' + clientId + '&client_secret=' + clientSecret + '&v=20180911';
  try{
    const response = await fetch(urlToFetch)
    if (response.ok) {
      //console.log(response)
      const jsonResponse = await response.json();
     // console.log(jsonResponse)
      const venues = jsonResponse.response.groups[0].items.map(item => item.venue);
      //console.log(venues)
      return venues;
    }
    else {
      throw new Error('Request failed!')
    }
  }
  catch(error) {
    //console.log(error.message)
  }
}

const getForecast = async () => {
const urlToFetch = `${forecastUrl}${apiKey}&q=${$input.val()}&days=4&hour=11`;
  try{
    const response = await fetch(urlToFetch);
    if (response.ok) {
      const jsonResponse = await repsonse.json();
      //console.log(jsonResponse);
      const days = jsonResponse.forecast.forcastday
      return days;
    } else {
      throw new Error('Requet failed!')
    }
  }
  catch(error) {
    console.log(error.message)
  }
}


// Render functions
const renderVenues = (venues) => {
  $venueDivs.forEach(($venue, index) => {
    // Add your code here:
const venue = venues[index];
    const venueIcon = venue.categories[0].icon;
    const venueImgSrc = `${venueIcon.prefix}bg_64${venueIcon.suffix}`;
    let venueContent = createVenueHTML(venue.name, venue.location, venueImgSrc );
    $venue.append(venueContent);
  });
  $destination.append(`<h2>${venues[0].location.city}</h2>`);
};

const renderForecast = (days) => {
  $weatherDivs.forEach(($day, index) => {
    // Add your code here:
const currentDay = days[index]
    let weatherContent = createWeatherHTML(currentDay);
    $day.append(weatherContent);
  });
}

const executeSearch = () => {
  $venueDivs.forEach(venue => venue.empty());
  $weatherDivs.forEach(day => day.empty());
  $destination.empty();
  $container.css("visibility", "visible");
  getVenues().then(venues => renderVenues(venues));
  getForecast().then(forecast => renderForecast(forecast));
  return false;
}

$submit.click(executeSearch)
2 Likes

Mispelling errors, that’s your issue:

const getForecast = async () => {
const urlToFetch = `${forecastUrl}${apiKey}&q=${$input.val()}&days=4&hour=11`;
  try{
    const response = await fetch(urlToFetch);
    if (response.ok) {
      const jsonResponse = await repsonse.json(); // should be: await response.json();
      //console.log(jsonResponse);
      const days = jsonResponse.forecast.forcastday  //should be: jsonResponse.forecast.forecastday
      return days;
    } else {
      throw new Error('Requet failed!')
    }
  }
  catch(error) {
    console.log(error.message)
  }
}

Dude, how have you got 4 elements in you weatherDiv array??? There’s only supposed to be one and it should be called weatherDiv not plural 's. Did you add more?

Hello, folks

I have the same issue. I then doublechecked the stuff, and it does not seem to have any issue? I checked the hints and everything seems to be in order. Can anyone please tell me what’s going on here?

// Foursquare API Info
const clientId = '5WSXLPJLEUCGZHW14K33VF3SI1BTLC5NSQ4TN0OXIGOMNZDO';
const clientSecret = '1KQ1VLJWCK5CYNGOIXIEXSE5YJCKDFTXA5FVI3OAKDFO5RXJ';
const url = 'https://api.foursquare.com/v2/venues/explore?near=';

// OpenWeather Info
const openWeatherKey = '36b61d5bb78c8e6ba4c05e00d7c6961e';
const weatherUrl = 'https://api.openweathermap.org/data/2.5/weather';

// Page Elements
const $input = $('#city');
const $submit = $('#button');
const $destination = $('#destination');
const $container = $('.container');
const $venueDivs = [$("#venue1"), $("#venue2"), $("#venue3"), $("#venue4")];
const $weatherDiv = $("#weather1");
const weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

// Add AJAX functions here:
const getVenues = async () => {
  const city = $input.val();
  const urlToFetch = `${url}${city}&limit=10&client_id=${clientId}&client_secret=${clientSecret}&v=20201229`;

  try {
    const response = await fetch (urlToFetch);
    if (response.ok){
      console.log(response);
      const jsonResponse = await response.json;
      console.log(jsonResponse);
      const venues = jsonResponse.response.groups[0].items.map(item => item.venue);
      console.log(venues);
      return venues;
     }
     else {
       throw new Error('Request failed!');
     }
  }
  catch(error){
    console.log(error);
  }
};

const getForecast = async () => {
  const urlToFetch = `${forecastUrl}${apiKey}&q=${input.val()}&day=4&hour=11`;
  try {
    response = await(urlToFetch);
    if(response.ok){
      const jsonResponse = await response.json();
      console.log(jsonResponse);
      const days = jsonResponse.forecast.forecastDay;
      return days;
    } else {
      throw new Error('Request failed!');
    }

  }
  catch (error) {
    console.log(error);
  }
};


// Render functions
const renderVenues = (venues) => {
  $venueDivs.forEach(($venue, index) => {
    const venue = venues[index];
    const venueIcon = venue.categories[0].icon;
    const venueImgSrc = `${venueIcon.prefix}bg_64${venueIcon.suffix}`;
    let venueContent = createVenueHTML(venue.name, venue.location, venueImgSrc);
    $venue.append(venueContent);
  });
  $destination.append(`<h2>${venues[0].location.city}</h2>`);
}

const renderForecast = (day) => {
  // Add your code here:
  const weatherContent = createWeatherHTML(day);
  $weatherDiv.append(weatherContent);
};
  
	let weatherContent = '';
  $weatherDiv.append(weatherContent);


const executeSearch = () => {
  $venueDivs.forEach(venue => venue.empty());
  $weatherDiv.empty();
  $destination.empty();
  $container.css("visibility", "visible");
  getVenues().then(venues => renderVenues(venues));
  getForecast().then(forecast => renderForecast(forecast));
  return false;
}

$submit.click(executeSearch)

Hello,

You use it correctly in your getForecast() function, but in your getVenues() function you have this:

Once you fix that, you’ll see the next error message about the incorrect variables being used in getForecast() but those error messages will be a lot more obvious.

1 Like

EDIT2: Ok. Apologies for this, but I fixed it. Instead of "return"ing the response of weather data, I was “logging” it in “console”, and hence I could not see the result. I went back to each step of the way, and then realised it was console.log and not return json.response. Once I fixed it, it was done!> Thanks for helping point out the first error!

Thanks a lot for this help. These tiny mistakes, lol. Not sure how I missed it in console.

I went back and I did change the values for it (had to open the hint and copy those in because I didn’t read the step properly. But now I am stuck on this error, but this is all using the code in hints that was provided by the exercise, so I’m not sure why weather doesn’t render. Perhaps if I could get a better explanation of this error? Is this related to something with the “helperFunction” file? Because that’s the only place where I see ‘main’ being defined (in the section of converting temperatures). Updated code below:

// Foursquare API Info
const clientId = '5WSXLPJLEUCGZHW14K33VF3SI1BTLC5NSQ4TN0OXIGOMNZDO';
const clientSecret = '1KQ1VLJWCK5CYNGOIXIEXSE5YJCKDFTXA5FVI3OAKDFO5RXJ';
const url = 'https://api.foursquare.com/v2/venues/explore?near=';

// OpenWeather Info
const openWeatherKey = '36b61d5bb78c8e6ba4c05e00d7c6961e';
const weatherUrl = 'https://api.openweathermap.org/data/2.5/weather';

// Page Elements
const $input = $('#city');
const $submit = $('#button');
const $destination = $('#destination');
const $container = $('.container');
const $venueDivs = [$("#venue1"), $("#venue2"), $("#venue3"), $("#venue4")];
const $weatherDiv = $("#weather1");
const weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

// Add AJAX functions here:
const getVenues = async () => {
  const city = $input.val();
  const urlToFetch = `${url}${city}&limit=10&client_id=${clientId}&client_secret=${clientSecret}&v=20201229`;

  try {
    const response = await fetch (urlToFetch);
    if (response.ok){
      console.log(response);
      const jsonResponse = await response.json();
      console.log(jsonResponse);
      const venues = jsonResponse.response.groups[0].items.map(item => item.venue);
      console.log(venues);
      return venues;
     }
     else {
       throw new Error('Request failed!');
     }
  }
  catch(error){
    console.log(error);
  }
};

const getForecast = async () => {
  const urlToFetch = `${weatherUrl}?&q=${$input.val()}&APPID=${openWeatherKey}`;
  try {
    response = await(urlToFetch);
    if(response.ok){
      const jsonResponse = await response.json();
      console.log(jsonResponse);
      const days = jsonResponse.forecast.forecastDay;
      return days;
    } else {
      throw new Error('Request failed!');
    }

  }
  catch (error) {
    console.log(error);
  }
};


// Render functions
const renderVenues = (venues) => {
  $venueDivs.forEach(($venue, index) => {
    const venue = venues[index];
    const venueIcon = venue.categories[0].icon;
    const venueImgSrc = `${venueIcon.prefix}bg_64${venueIcon.suffix}`;
    let venueContent = createVenueHTML(venue.name, venue.location, venueImgSrc);
    $venue.append(venueContent);
  });
  $destination.append(`<h2>${venues[0].location.city}</h2>`);
}

const renderForecast = (day) => {
  const weatherContent = createWeatherHTML(day);
  $weatherDiv.append(weatherContent);
};
	let weatherContent = '';
  $weatherDiv.append(weatherContent);


const executeSearch = () => {
  $venueDivs.forEach(venue => venue.empty());
  $weatherDiv.empty();
  $destination.empty();
  $container.css("visibility", "visible");
  getVenues().then(venues => renderVenues(venues));
  getForecast().then(forecast => renderForecast(forecast));
  return false;
}

$submit.click(executeSearch)
1 Like

You’re welcome. Sometimes the errors even more cryptic because it pops up in code you didn’t write since you’re passing data around.

It’s related to the helper function only in that it’s receiving data it doesn’t like. That data is coming from a series of function calls though. I’ll walk you through my thought process for debugging this to see if it helps you in the future. In this, we know that it’s also logging “Request failed!” and/or it isn’t showing the JSON for the weather, but you are seeing JSON from the other. For that reason, we’d want to dive deeper into the getForecast() function:

We know we aren’t seeing JSON from your console.log() so it never enters that block of code. The condition stopping it is if(response.ok). The response value is being set in the previous line:

 response = await(urlToFetch);

We could add some logging after this line to check what response is getting assigned, but in this case, we know that await(urlToFetch) isn’t valid because fetch is missing.


If you fix that, you’ll see JSON in your console for weather. You’ll get a different error, but that’s still progress!

Hint about the next error

It’s going to complain about Cannot read property 'forecastDay' of undefined
If you examine the JSON by clicking the chevron (the little triangle thingy) next to the weather JSON, you’ll see that the forecast.forecastDay you added to jsonResponse to get the data isn’t valid. You can remove that. You only need to return the JSON

1 Like

The ‘fetch’ was the first thing I went back to fix. Thanks for catching that. And yup. Removed the forecast.forecast days and works fine without. Thanks a lot for bearing with me here. This logging sure did help learn a bit more about the errors, esp. how and where the ‘main’ error was coming from, and your explanation is quite similar to how I explored this and other problems, so that’s a plus! Thank you!

1 Like

Thank you for your help. I was rushing a bit and missed few important details in the process. I am baffled how I managed to miss to return venues in const getVenues.