Set image to id based on two arrays(solved)

Hello All.

I am working on the Local weather app, which have taken me a insane amount of time. I am able to see light in the tunnel now, but have a issue I don`t seem to be able to solve when trying to set icons to the weekly forecast.

I could solve this the “easy” way by just write big amounts of repeating code, but would very much like to solve this in a more elegant way (and understand it at the same time :slight_smile: )

So at the bottom of this code I have a function called setWeekIcon where i have a for loop which function is to loop over an array of weather icons. Then I try to pass in arguments from a iconArray, which again holds the weather forecast icons from the Dark Sky API.

I tried to use a IF ELSE condition, but understood that this is not the way to go, as I then only will be able to fulfill the two first conditions. Since then I have been trying to search the web for inspiration, but have not been able to figure it out.

Appreciate it if anybody have some advice and I apologize if I don`t make any sense.

BR
Tommy

//Global variables
var units = ‘si’;
var lat;
var lon;
var temp;
//var icon = " “;
var resp;
var dailyTemp;
var weekday = [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”]; //to find day of the week
var dayArray = ; //to store days of the week
var iconArray = ; //to store icon values
var tempArray = ; //to store temps
//Get weather data
function getWeather(longitude, latitude) {
$.getJSON(‘How Dark Sky users can use the Apple Weather app - Apple Support’ + latitude + ‘,’ + longitude + ‘?callback=?&units=’ + units + ‘’, function (json) {
temp = json.currently.temperature;
var icon = json.currently.icon;
console.log(json);
$(”#temp").html(Math.round(temp) + (‘°C’));
$(“#desc”).html(json.currently.summary);
$(“#forecast”).html(json.daily.summary);
var weatherIcon = json.daily.data[i].icon;
iconArray.push(weatherIcon);
var dailyTemp = json.daily.data[i].apparentTemperatureMax;
tempArray.push(dailyTemp);

  var imageArray = [
  	{
  		"src": "icons/b100/09.png"
  		, "title": "rain"
  		, "imageCaption": "Image caption for rain"
  }
  	, {
  		"src": "icons/b100/mf/01n.50.png"
  		, "title": "clear-night"
  		, "imageCaption": "Image caption for clear night"
  }
  	, {
  		"src": "icons/b100/01d.png"
  		, "title": "clear-day"
  		, "imageCaption": "Image caption for clear day"
  }
        , {
  		"src": "icons/b100/13.png"
  		, "title": "snow"
  		, "imageCaption": "Image caption for snow"
  }
        , {
  		"src": "icons/b100/12.png"
  		, "title": "sleet"
  		, "imageCaption": "Image caption for sleet"
  }
        , {
  		"src": "icons/b100/15.png"
  		, "title": "fog"
  		, "imageCaption": "Image caption for fog"
  }
        , {
  		"src": "icons/b100/03d.png"
  		, "title": "partly-cloudy-day"
  		, "imageCaption": "Image caption for partly cloudy day"
  }
        , {
  		"src": "icons/b100/01n.png"
  		, "title": "clear-night"
  		, "imageCaption": "Image caption for partly clear night"
  }
        , {
  		"src": "icons/b100/mf/03n.50.png"
  		, "title": "partly-cloudy-night"
  		, "imageCaption": "Image caption for partly partly cloudy night"
  }
  	];
    function setWeekIcon(title1,title2,title3,title4,title5,title6) {
  	for (var i = 0; i < imageArray.length; i++) {
  		if (imageArray[i].title == title1) {
  			$('#icon2').attr('src', imageArray[i].src);
  		}else if (imageArray[i].title == title2) {
  			$('#icon3').attr('src', imageArray[i].src);
            }else if (imageArray[i].title == title3) {
  			$('#icon4').attr('src', imageArray[i].src);
            }else if (imageArray[i].title == title4) {
  			$('#icon5').attr('src', imageArray[i].src);
            }else if (imageArray[i].title == title5) {
  			$('#icon6').attr('src', imageArray[i].src);
            }else if (imageArray[i].title == title6) {
  			$('#icon7').attr('src', imageArray[i].src);
            }
  	}
  	return "Error";
  }
  setWeekIcon(iconArray[0],iconArray[1],iconArray[2],iconArray[3],iconArray[4],iconArray[5]);

});
};

@tomstrand You can try using the index position as a string for building the id attribute.

	var imageArray = [
		{
			"src": "icons/b100/09.png"
			, "title": "rain"
			, "imageCaption": "Image caption for rain"
	}
		, {
			"src": "icons/b100/mf/01n.50.png"
			, "title": "clear-night"
			, "imageCaption": "Image caption for clear night"
	}
		, {
			"src": "icons/b100/01d.png"
			, "title": "clear-day"
			, "imageCaption": "Image caption for clear day"
	}
        , {
			"src": "icons/b100/13.png"
			, "title": "snow"
			, "imageCaption": "Image caption for snow"
	}
        , {
			"src": "icons/b100/12.png"
			, "title": "sleet"
			, "imageCaption": "Image caption for sleet"
	}
        , {
			"src": "icons/b100/15.png"
			, "title": "fog"
			, "imageCaption": "Image caption for fog"
	}
        , {
			"src": "icons/b100/03d.png"
			, "title": "partly-cloudy-day"
			, "imageCaption": "Image caption for partly cloudy day"
	}
        , {
			"src": "icons/b100/01n.png"
			, "title": "clear-night"
			, "imageCaption": "Image caption for partly clear night"
	}
        , {
			"src": "icons/b100/mf/03n.50.png"
			, "title": "partly-cloudy-night"
			, "imageCaption": "Image caption for partly partly cloudy night"
	}
		];

for (var i = 0; i < imageArray.length; i++) {
    var $icon = $('#icon' + i);
    $icon.attr('src', imageArray[i].src);
}

Does that fit your problem?

Thanks for the reply. I will try to see when I’m back at the computer. Took me some time before I understood what you did, but it seems it just may work😊

Great! Let me know if it works :slight_smile:

I tested just now, and you suggestion worked for placing the icons to the id tags. Problem is that they were placed in the order they are set in the array, not taking in consideration the iconArray which contains the actual weather condition array for the forecast. Have attached a screenshot that show how the icons were placed. The iconArray from the API outputs: [“rain”, “partly-cloudy-day”, “snow”, “snow”, “snow”, “snow”]

If only I now are able to use you solution and somehow assign the values from the iconArray. The temp and day values in the screenshot is accurate, as it was easy to just place the text values directly from the API array.

Ok. I think I had misunderstood your first question, sorry!

By your description, it looks like you’ll find the Array.prototype.find method useful. See the docs here: Array.prototype.find() - JavaScript | MDN

The find() method returns a value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

Could you try the following code? It loops over the array of icons and for each icon, it finds the corresponding image.


var currentIcon;
var $currentIconElement;

// loop over iconArray
for (var i = 0; i < iconArray.length; i++) {
    // retrieve the current Icon
    currentIcon = iconArray[i];

    // retrieve the icon element
    $currentIconElement = $('#icon' + i);
    
    // retrieve the corresponding image from the imageArray
    var image = imageArray.find(function (imageCandidade) {
        return imageCandidate.title === currentIcon;
    });

    $currentIconElement.attr('src', image.src);
}
1 Like

Also, even more basic answer: when you need to take action based on one of multiple possible “cases”… yes, you could use a whole string of if {} else if {} else if… or you could use a switch! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

No need to apologize. My explanation was confusing at best…:sweat_smile:

I locked at the Array.prototype.find earlier but was not able to grasp how to implement it.

Thank you for the example. I will try as soon as possible. I am actually quite impressed how quick you were able to come up with that, It would at my current level take me days or even weeks to be able to think that out by myself.

Yes, I tried if, else if , else. And it did work as long as all the icons were different, as soon as two or more of the same type appeared in the array it did not,

I also tried switch, and that worked, but at least the way I implemented it there was a tremendous amount of code to consider all cases :slight_smile:

Thank you, thank you thank you!!! @simonfan
It worked perfectly. All I needed to do was to rename my #id tags as the index started at 2 (#icon2, #icon3 and so on) not 0.

@tomstrand, I’m happy it worked for you :slight_smile:

You’ll love Array.prototype.find. It is tremendously powerful: it is a method of all arrays (it belongs to Array.prototype), and basically you pass it a function that will be called once per item in the array. The function should return a boolean, true meaning “yes, this item is the one I’m looking for, stop iterating” and false meaning “nope, let me check the next item”.

Good luck with your projects! :wink:

1 Like