Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Can't Figure This One Out

Hi guys,

I'm having trouble with a personal project I'm working on. It's a website which displays weather information from the openweathermap.org API.

The part I'm stuck on is getting my site's background image to change depending on the current weather. I've written a function to do this and it works if I manually enter the current weather conditions but I can't for the life of me seem to get it to work based on the weather conditions called from the API responseText.

So my code looks something like this:-

Associative Array for finding image names

var conditions = [{Thunderstorm: "images/stormy.jpg",
                  Drizzle: "images/rainy.jpg",
                  Rain: "images/rainy.jpg",
                  Snow: "images/snowy.jpg",
                  Clear: "images/sunny.jpg",
                  Clouds: "images/overcast.jpg",
                  Extreme: "images/stormy.jpg"}];

Variable to store the current weather conditions from API ("data" is the variable which has the JSON responseText)

var apiConditions = data.list[0].weather[0].main;

Function to change background image

function setBackground(currentConditions) {
    body.style.background = "url('" + currentConditions + "')";
    body.style.backgroundSize = "cover";
    body.style.backgroundRepeat = "no-repeat";
  };

Function call

setBackground(conditions[0].apiConditions);

Where it all seems to be falling apart is the value stored in the apiConditions variable is not being passed to the function call. If I call the function as setBackground(conditions[0].Rain) it works.

I've tried checking the value of the apiConditions variable through console.log(apiConditions) and it is returning a valid value i.e. Rain as per the above example, but if I try console.log(conditions[0].apiConditions) it comes back as undefined.

An example of the API call can be found here: http://samples.openweathermap.org/data/2.5/forecast?lat=35&lon=139&appid=b1b15e88fa797225412429c1c50c122a1

I'm lost.

Any help/ideas would be greatly appreciated.

Cheers Don

2 Answers

andren
andren
28,558 Points

Try this:

setBackground(conditions[0][apiConditions]);

If I understand your code setup and issue correctly that should work.

When you use . to access a property JavaScript will treat any text you give it literally, so conditions[0].apiConditions will make it look for a property called apiConditions within conditions[0]. By using bracket notation instead JavaScript will in fact replace variables with the values they store. Which is what I'm assuming you want to happen.

As an aside why is conditions an array? If you only intend for it to store a single object then you can just assign that object to it directly. That why you would not have to use [0] every time you pulled a value out of it.

You absolute legend! Thanks for your help :-)

On the conditions array, I thought that is how I had to store a heap of key:value pairs. Are you saying I didn't need the {} inside the array and I could have just had [key:value, key:value ....]?

Thanks again Don :-)

andren
andren
28,558 Points

No, I'm actually saying the opposite. In JavaScript square brackets [] are used to denote an array, which is basically just a list of elements, it's only needed if you actually intend to store multiple elements in the array. Objects which are denoted by curly braces {} and store key: value pairs are considered to be a single element, so you don't have to use an array to store them.

So in other words you don't need the square brackets [] on the outside, just the {} on the inside, like this:

var conditions = {Thunderstorm: "images/stormy.jpg",
                  Drizzle: "images/rainy.jpg",
                  Rain: "images/rainy.jpg",
                  Snow: "images/snowy.jpg",
                  Clear: "images/sunny.jpg",
                  Clouds: "images/overcast.jpg",
                  Extreme: "images/stormy.jpg"};

Conditions would then be accessed like this conditions.Rain or conditions[apiConditions] depending on the syntax you want to use.

Gotcha, thanks again for your help :-)