Multiple If Blocks I NEED HELP PLEASE

I m working on the weather app and i want to run two if blocks. basically, i want a background to display based on the type of weather (specifically the weather ID i get from openweathers api) - i have done this part successfully. i also want to display a different background it is night time(i already have that variable i call it hour)

what i cant figure out is how to have this work. im guessing i need an outer if block to run for the hours variable and then just run my id variable block of the else of that…im sorry im a week into this stuff so i might not be explaining this well.

i ll attach my pen. i have commented out the if statement that has my night time conditions.
ANY help with this would be greatly appreciatted

link - http://codepen.io/benjaminadk/pen/jmabdb/

If you do check for range conditions like if something is in range you must provide valid ranges. for example :slight_smile:

var rainy = (id === 800 || id === 801);
var sunny = (id > 200 && id < 300);
var partiallyCloudy = (id > 300 && id < 500);

if(sunny) {
// code for sunny
} else if(rainy) {
// code for rain
.
.
etc.

Hope that helps a bit :slight_smile:

To be clear your ranges must be such that there isn’t a possibility for them to overlap. That’s the point.

i get that i think. but my prob is i want to execute background based on two different variables. for variable one there are two conditions night or day. but within day there are is rainy sunny cloudy etc

so if its night i just have one background no matter what the weather and if its day there are all the different background that ive chosen’

i have made my if block work for the weather variables but i cant figure the code to have it check day vs night first
again sorry im a newb for sure

Ok, I see the issue. Well, you have #display element where you putting your background. Thing is that you want to place image on it when it is night and again image that satisfy condition when it is rainy or depends on weather. So basically you put background image when it is night and later you overwrite it by another condition when you see the temperature.
Now you have couple of choices, one is to define small div that will hold image for night or day and main #display that will hold main background image for temperature. You cannot place 2 background images in the background.
Well you can actually but you must define z-index for each image which I don’t recommend. Easy solution would be to define another small div that will have backgound image depending if it’s day or night and main background depends on temperature or vice versa.

Multiple backgrounds work in a way that you must provide multiple urls, like :slight_smile:
background-image : url(url1) , url(url2) ;
So if you wanna go that way you have to concatinate url’s to include 2 - one for night/day and one for weather but in a single background-image property like in above example. This way you are overwriting it.
Check out : https://www.w3schools.com/css/css3_backgrounds.asp

Here is a code snippet :slight_smile:

      var backgroundUrls = ""; // variable to store multiple backgrounds
      if(hour > 5 && hour < 23){
        // daytime
        backgroundUrls = "url('https://i.kinja-img.com/gawker-media/image/upload/s--EUYvNPnM--/c_scale,f_auto,fl_progressive,q_80,w_800/ke9svxml3ctkvgix59xl.jpg') ";
      } else {
       // nightime
	backgroundUrls = "url('https://i.kinja-img.com/gawker-media/image/upload/s--EUYvNPnM--/c_scale,f_auto,fl_progressive,q_80,w_800/ke9svxml3ctkvgix59xl.jpg') ";
      }
      
      if(id === 800 || id === 801){
        backgroundUrls += ",url ("https://ak5.picdn.net/shutterstock/videos/1747219/thumb/1.jpg")";
        $('#display').css({'background-image': backgroundUrls, 'background-position': '-80px 0'});
      }

BTW. If you are worried about getting current hour you do it correctly, so 1 = 1 AM

huh???

so in your snippet backgroundUrls would end up having two urls. because of +=

when that goes into .css your saying the browser will take the second url???

Yes, you might fix the size and position but you can combine multiple backgrounds like

element.css(“background-image”,“url(http://img1) ,url(http://img2)”);

well thanks this has been helpful ill see what i can come up with

I would recommend looking at how you are structuring your code and how you could begin extracting things that change based on conditions into a container object with property objects which contain the data you want to apply based on a condition.

For example, my weather app can be found here:

I wrote it so that the UI would change color schemes based on time of day and weather conditions (including a special twilight condition to give a sunrise/sunset color scheme).

Rather than hard coding a bunch of if statements with weather codes, I pulled all of that data into a config object, which I could then reference directly.

This is my function for inserting current weather conditions and updating UI CSS classes based on the data:

  function ui_insert_current_conditions( $body, conditions ){
    
    const weather_condition = config.weather_conditions[ conditions.weather[ 0 ].id ];
    const $container     = $body.find( 'div.middle' );
    const classes_to_add = [];
    const icons = weather_condition.icons;
    
    classes_to_add.push( weather_condition.css_class );
    
    $container
      .find( 'h1.location_name' )
        .text( conditions.name )
      .end()
      .find( 'h3.current_conditions' )
        .text( weather_condition.condition )
      .end()
      .find( 'div.weather_icon img.day' )
        .attr( 'src', ( icons ) ? icons.day : '' )
      .end()
      .find( 'div.weather_icon img.night' )
        .attr( 'src', ( icons ) ? icons.night : '' )
      .end();
    
    ui_insert_temperature( $container.find( 'div.info.temperature' ), conditions, 'F' );
    ui_insert_wind( $container.find( 'div.info.wind'), conditions );
    ui_insert_location_data( $container.find( 'div.info.latlong' ), conditions.coord );
    
    $container.find( '.info' ).removeClass( 'hidden' );
    
    $body
        .removeClass( config.condition_classes )
        .addClass( classes_to_add.join( ' ' ) );

  }

All weather_condition objects are structured the same way. This is an example of a weather_condition object found on the config object:


     {
      '200': {
        'condition': 'Thunderstorms with light rain.',
        'css_class': 'thunderstorm',
        'icons'    : {
          'day'   : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png',
          'night' : 'http://www.michealhallphotography.com/mystuff/fcc/weatherapp/images/icons/01.png'
        }
      }

If you read through the function, you’ll see that it’s updating the interface, but it has absolutely no idea what the current conditions are - and it shouldn’t care what they are. All it is doing is getting a reference to a weather configuration object based on the conditions passed in, and then applying that configuration data to the UI.

That makes it a generic function which can be extended at any time by adding more weather conditions to the config object, with no changes whatsoever to the code itself. No more if or else statements. Your ui function is kept very lean and clean.

It’s a very good idea to separate out data from logic. Make the logic as generic as possible. Structure the data consistently. Then functions can become much, much simpler.

~Micheal

No problem, see what you want to achieve as end result. If you wanna combine two backgrounds that this is the way, just like I said you will have to work on positioning because they will be combined and if they are on the same position and same sizes they will stack on top of each other. I would personally go the other way of displaying day/night in small div background and main for the weather, but it is cool to try to combine them. Depends what you wanna achieve, but your logic is correct, you are having good first if condition and getting hour properly. Just showing 2 backgrounds on the same div require little positioning and sizing. Nothing else is wrong in your code.

@michealhall that is all correct and good practice, yet I think he is a beginner and playing with properties and see what he can do. Separation of concerns in terms of data and display I think its might still deep water for him. But yep it is pro to separate data from display, just might be confusing at the beginning I would say.
BTW. Your weather app is quite amazing

i understand what you are saying Micheal. about logic being as general as possible. your code was hard to follow for me…i have no idea what const or ui mean in the context of javascript. it looks like you built your own objects to have all the data you need based on weather id.

1 Like

Thanks @mirkoacimovic!

Yes, it’s hard sometimes to judge where a person is on the learning curve. And I definitely don’t want to put up barriers to learning by going at things to steeply or quickly.

Those recommendations simply came from me making the same mistakes many times - hopefully others can skip them and move on more quickly than I did! :slight_smile:

1 Like

@benjaminadk - Sorry, I didn’t mean to post anything too far ahead.

To help clarify - yes, I did pull as much data out into my own config objects in advance of coding anything. I knew I wanted to make things as general as possible and when I looked at the API information from the weather data, I saw that it could be coming through consistently and that I would then be able to build my own objects based on the data I could expect from the weather API calls. Shorter functions are easier to read and digest.

const in Javascript is another way of binding a label in the code to a value in memory (the same as a variable) … except, in this case, you cannot re-assign what is assigned to the const. For example:


// USING VAR, THIS IS COMPLETELY OK ...

var a_variable = 'I am a variable';

a_variable = 'I am also a variable';


// BUT YOU CANNOT DO THAT WITH const
const this_constant = 'I am a constant!';

// THIS WILL THROW AN ERROR - YOU CANNOT RE-ASSIGN A CONSTANT
this_constant = 'I am a new value!';

// HOWEVER, IF A CONSTANT REFERENCES AN OBJECT OR AN ARRAY YOU CAN CHANGE PROPERTIES OF THE OBJECT OR ELEMENTS IN THE ARRAY ...
const array_constant = [ 1, 2, 3, 4 ];

// THIS IS OK
array_constant.push( 5 );

// THIS IS ALSO OK
array_constant[ 0 ] = 'A changed value';

// THIS WILL THROW AN ERROR YOU'RE TRYING TO RE-ASSIGN THE CONSTANT TO POINT TO A DIFFERENT ARRAY
const array_constant = [];

// THIS WORKS THE SAME FOR OBJECTS
const object_constant = {};

// NOPE
object_constant = {}; // THIS IS A DIFFERENT OBJECT

// THIS IS OK
object_constant.color = 'red';

The argument for const is one of code organization mostly. It prevents you from goofing later by re-assigning a value when perhaps you shouldn’t have and makes things pretty explicit since you can’t re-assign them later.

More at MDN:

In the case of “ui”, that’s just an abbreviation for user interface. For this project, I prefixed functions based on what they did. So, the function I posted modified the user interface, so it started with “ui_”. It was done mostly as a self-documenting thing so that, at a glance, I could know generally what sort of thing the function did.

A great deal of coding is about writing it so that - when you or others - come back to it later, it is as easy to read and understand as possible.

Hope this clarifies things a bit!

~Micheal