Cannot get weather icons to display on Weather App

I have linked to https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.css in the CSS settings for Code Pen. Now when I try to display a weather icon, as below:

<div class="row text-center">
    <header>
       <h1>L<i class="wi-day-sunny"></i>cal Weather</h1>
    </header>
</div>

it refuses to show the icon. I’m not sure if this is just because perhaps I’m doing something wrong with Code Pen or another problem.

Thanks for any suggestions.

<div class="row text-center">
    <header>
       <h1>L<i class="wi-day-sunny"></i>cal Weather</h1>
    </header>
</div>

If I’m not wrong, you missed a wi before the wi-day-sunny there.

<i class="wi wi-day-sunny">

Actually, you can see it in the link to the library you just mentioned. One of the first styles is:

.wi {
  display: inline-block;
  font-family: 'weathericons';
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

That’s the first style you have to implement so it gets the font-family, display and all the properties.

Happy coding!

I have set up a switch statement to change the weather icons according to the weather.id in the fcc weather api.
For some reason it’s not showing the icons. The console is giving me a json not defined error, but I’m not sure how to fix that or whether that’s the reason it’s not working.

Here’s the HTML code in question:

<div class="wi"> 
</div>

Here’s the CSS for each weather icon I want to include:

.wi-thunderstorm:before {
  content: "\f01e";
}

.wi-showers:before {
  content: "\f01a";
}

.wi-rain:before {
  content: "\f019";
}

.wi-snow:before {
  content: "\f01b";
}

.wi-day-fog:before {
  content: "\f003";
}

.wi-day-sunny:before {
  content: "\f00d";
}

.wi-day-cloudy:before {
  content: "\f002";
}

And here’s the Javascript in question:

function fetchWeather(position) {
  var lat = "lat=" + position.coords.latitude;
  var lon = "lon=" + position.coords.longitude;
  const uri = `${ROOT_URI}${lat}&${lon}`;
  $.getJSON(uri, function(json){
    $(".city").html(json.name + ",&nbsp;");
    $(".country").html(json.sys.country);
    tempInCelsius = parseFloat(json.main.temp).toFixed();
    tempInFahrenheit = Math.round(tempInCelsius*9/5 + 32);
    tempFormat = " " + String.fromCharCode(176); 
    $(".temperature").html(tempInCelsius + tempFormat);
    $(".scale").html("C");
    $(".weather").html(json.weather[0].main);
    createIcon(json);
  });
}

function createIcon(weatherData) {
  var weatherId = weatherData.weather[0].main;
  switch (weatherId) {
    case (weatherId >= 200 && weatherId < 300): // thunderstorm
      placeIcon(weatherId)
      break;
    case (weatherId >= 300 && weatherId < 400): // showers
      placeIcon(weatherId)
      break;
    case (weatherId >= 500 && weatherId < 600): // rain
      placeIcon(weatherId)
      break;
    case (weatherId >= 600 && weatherId < 700): // snow
      placeIcon(weatherId)
      break;
    case (weatherId >= 700 && weatherId < 800): // fog
      placeIcon(weatherId)
      break;
    case (weatherId == 800): // sunny
      placeIcon(weatherId)
      break;
    case (weatherId >= 801 && weatherId <= 804): // cloudy
      placeIcon(weatherId)
      break;
    default:
      $('.weatherIcon').addClass('wi-day-sunny');
  }
}

function placeIcon(weatherId) {
  $(".wi").addClass(weatherId);
}

My codepen is here: https://codepen.io/sanskrtapanditah/pen/qozxOG

Thanks in advance for any ideas. And, btw I did get the icon to display in the heading like I wanted before, following your advice.

You are not passing the correct value to the createIcon function. The weather property value is an array, with the first element containing an object with the id property.

json is not defined inside the createIcon function. Why not pass two arguments to createIcon? The first would be the corrected reference from above and the second would be the main property.

I changed the code to work with the array in the API:

function fetchWeather(position) {
  var lat = "lat=" + position.coords.latitude;
  var lon = "lon=" + position.coords.longitude;
  const uri = `${ROOT_URI}${lat}&${lon}`;
  $.getJSON(uri, function(json){
    $(".city").html(json.name + ",&nbsp;");
    $(".country").html(json.sys.country);
    tempInCelsius = parseFloat(json.main.temp).toFixed();
    tempInFahrenheit = Math.round(tempInCelsius*9/5 + 32);
    tempFormat = " " + String.fromCharCode(176); 
    $(".temperature").html(tempInCelsius + tempFormat);
    $(".scale").html("C");
    $(".weather").html(json.weather[0].main);
    createIcon(json.weather[0].id);
  });
}

function createIcon(weatherData) {
  var weatherId = weatherData.weather[0].id;
  var weatherType = weatherData.weather[0].main.toLowerCase();
  switch (weatherId) {
    case (weatherId >= 200 && weatherId < 300): // thunderstorm
      placeIcon(weatherType)
      break;
    case (weatherId >= 300 && weatherId < 400): // showers
      placeIcon(weatherType)
      break;
    case (weatherId >= 500 && weatherId < 600): // rain
      placeIcon(weatherType)
      break;
    case (weatherId >= 600 && weatherId < 700): // snow
      placeIcon(weatherType)
      break;
    case (weatherId >= 700 && weatherId < 800): // fog
      placeIcon(weatherType)
      break;
    case (weatherId == 800): // sunny
      placeIcon(weatherType)
      break;
    case (weatherId >= 801 && weatherId <= 804): // cloudy
      placeIcon(weatherType)
      break;
    default:
      $('.weatherIcon').addClass('wi-day-sunny');
  }
}

function placeIcon(weatherId) {
  $(".wi").addClass(weatherId);
}

But now the console is giving me an error:

Uncaught TypeError: Cannot read property ‘0’ of undefined
at createIcon (pen.js:80)
at Object.success (pen.js:75)

When I try to open those pages, they come up blank, so I can’t use the console to figure out the problem.
Am I going about this whole thing wrong? Should I not be using the weather id at all? I could just go the easy route and put background images in, but I thought I would learn more doing it this way. However, it’s really not working out well.

You have since changed your code a bit, but I uncommented the code to get the error you were seeing. The reason you were getting that error is because you passed json.weather[0].id as the argument to createIcon (which is fine), but inside the createIcon function weatherData is the id you passed into the function so it will not have a weather property, which is why the following line had the error:

var weatherId = weatherData.weather[0].id;

If you would have just passed json as the argument value, then you would have been able to reference weatherData as you were trying to do.

Also, remember that the id property is a string, so you need to convert it into a number when comparing it to the various values in your case statements. Also, you will need to use switch (true), because you want to test if your expressions evaluate to true and not weatherId.

Finally, you might want to check the class names from the css library you loaded, because I do not see classes by the name “clear”. I do see classes like “wi-day-clear” and “wi-night-clear”.