jQuery: How do I append an array item in a loop? - javascript
I'm trying to create a weather forecast page for a website.
I am using OpenWeatherMap to retrieve JSON data.
I want to loop through the "weather" array from the JSON, which contains objects that hold weather information.
This is the JSON shown in the console after using console.log (screenshot for readability):
Here is my jQuery/JavaScript:
$.getJSON("https://api.openweathermap.org/data/2.5/weather?lat=57.995221&lon=-6.761395&units=metric&APPID=myAPIkey", function(data){
var currWeather = [data.weather];
var len = currWeather.length;
for (i = 0; i > len; i++) {
$("#weather").append(currWeather[i].main);
$("#desc").append(currWeather[i].description);
}
var clouds = data.clouds.all;
$("#clouds").append(clouds);
var temp = data.main.temp;
$("#temp").append("Temperature: " + temp + "ยบC");
var humidity = data.main.humidity;
$("#humidity").append("Humidity: " + humidity + "%");
var pressure = data.main.pressure;
$("#pressure").append("Pressure: " + pressure);
console.log(data);
});
My HTML:
<div id="weatherBox">
<h2>Current Weather</h2>
<div id="mainWeather">
<div id="temp"></div></td>
<div id="weather"></div>
<div id="desc"></div>
<div id="icon"></div>
</div>
<br>
<div id="clouds"></div>
<div id="humidity"></div></td>
<div id="pressure"></div></td>
</div>
Basically, the only thing that isn't being displayed is the weather information. I have no errors or warnings in the console, am I doing this correctly?
Edit: I should add that in the json "weather" array, "0" and "1" are stored as strings. I tried to do:
$("#weather").append(currWeather[i.toString()].main);
Just to see if it would work. It did not.
A few things I found wrong with your code
You can access a property with dot notation or bracket notation so
either data.weather or data["weather"] not [data.weather]
your for loop should declare i as a var and it should be < the
length since you start at 0
The other properties should also be in the loop since they are in an
obj that is part of the array you are looping.
you accessed the other properties incorrectly it should be
weatherData[i].temp and not data.main.temp the main property is
a string, not an obj so you can't use a property accessor.
And of course you will have to do some additional formatting to make your display look pretty.
var data = {
weather: [{
main: "Drizzle",
description: "A light rain",
temp: 50,
humidity: 5,
pressure: 10
}, {
main: "Sunny",
description: "The sky is blue and so are you",
temp: 80,
humidity: 3,
pressure: 4
}]
}
var weatherData = data.weather;
var len = weatherData.length;
for (var i = 0; i < len; i++) {
var currWeather = weatherData[i];
//console.log(currWeather);
$("#weather").append(currWeather.main);
$("#desc").append(currWeather.description);
//var clouds = data.clouds.all;
//$("#clouds").append(clouds);
var temp = currWeather.temp;
//console.log(temp)
$("#temp").append(" Temperature: " + temp + "ยบC");
var humidity = currWeather.humidity;
$("#humidity").append(" Humidity: " + humidity + "%");
var pressure = currWeather.pressure;
$("#pressure").append(" Pressure: " + pressure);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="weatherBox">
<h2>Current Weather</h2>
<div id="mainWeather">
<div id="temp"></div>
</td>
<div id="weather"></div>
<div id="desc"></div>
<div id="icon"></div>
</div>
<br>
<div id="clouds"></div>
<div id="humidity"></div>
</td>
<div id="pressure"></div>
</td>
</div>
Try this:
var currWeather = data.weather;
You're trying to storing data in the wrong place.
Here is a working example on jsBin: https://jsbin.com/bijoyoyofo/1/edit?html,js,output
Basically
var currWeather = [data.weather];
should be
var currWeather = data.weather;
and
for (var i = 0; i > len; i++) {
should be
for (i = 0; i < len; i++) {
I also added a paragraph in the div but that is up to you.
I adjusted your document to include the jQuery $(document).ready() function, using an API key I found on Github for open weather. You can access the weather array from data.weather, as you see below. You also had the loop written incorrectly, as you needed the var i to be less than the length, not greater than. Here is a working sample of your code.
$(document).ready(function(){
var myAPIkey = 'bd5e378503939ddaee76f12ad7a97608';
$.getJSON("https://api.openweathermap.org/data/2.5/weather?lat=57.995221&lon=-6.761395&units=metric&APPID="+myAPIkey, function(data){
var currWeather = data.weather;
for (i = 0; i < currWeather.length; i++) {
$("#weather").append(currWeather[i].main);
$("#desc").append(currWeather[i].description);
}
var clouds = data.clouds.all;
$("#clouds").append(clouds);
var temp = data.main.temp;
$("#temp").append("Temperature: " + temp + "ยบC");
var humidity = data.main.humidity;
$("#humidity").append("Humidity: " + humidity + "%");
var pressure = data.main.pressure;
$("#pressure").append("Pressure: " + pressure);
console.log(data);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="weatherBox">
<h2>Current Weather</h2>
<div id="mainWeather">
<div id="temp"></div></td>
<div id="weather"></div>
<div id="desc"></div>
<div id="icon"></div>
</div>
<br>
<div id="clouds"></div>
<div id="humidity"></div></td>
<div id="pressure"></div></td>
</div>
Related
AWS Javascript SDK EC2 DescribeInstances
I am trying to get date & no. of instances spin-up on that day. Here is my code , i am beginner in development & in javascript. so forgive me in advance for any immature code. after getting startdate & end date , dates are stored in listDate array. hours of a day is stored in hourArray. then using JS SDK for AWS to get no. of instances spinned up on specific date. ec2.describeInstances is not working as expected here , sometimes , i got output from ec2.describeInstances correctly , but it is always picking end date in all while loop iterations. most of the time , ec2.describeInstances doesnt even execute. function applyFilters() { var listDate = []; demo1.innerHTML = ''; var startDate = document.getElementById("fromdate").value; var endDate = document.getElementById("todate").value; //alert(startDate); //alert(endDate); var dateMove = new Date(startDate); var strDate = startDate; while (strDate < endDate){ var strDate = dateMove.toISOString().slice(0,10); listDate.push(strDate); dateMove.setDate(dateMove.getDate()+1); }; //alert(listDate); //document.getElementById('demo1').innerHTML = "Your selected dates are"; //demo2.innerHTML += "<br>"; //document.getElementById('demo3').innerHTML = listDate; alert(listDate); var i = 0; var j = listDate.length; alert(j); while (i < j){ alert(i); alert(listDate[i]); var hourArray = []; var d = listDate[i]; for (var h = 0; h <= 9; h++) { hourArray.push(d + 'T' + '0' + h + '*'); } for (var m = 10; m <= 23; m++) { hourArray.push(d + 'T' + m + '*'); } alert(hourArray); var ec2 = new AWS.EC2(); AWS.config.update({ region: "xxxxxxx", accessKeyId: "xxxxxxxxxxxxxxxxxxxxx", secretAccessKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }); i++; var params = { Filters: [ { Name: 'launch-time', Values: hourArray }] }; //alert("Specified launch-times are: " + hourArray); ec2.describeInstances(params, function(err, data, d) { //alert(data); if (err) { //demo5.innerHTML = 'ERROR:' + err; console.log(err); } else { var no_of_inst = data.Reservations.length; //demo4.innerHTML += "<br>"; //document.getElementById('demo5').innerHTML = 'Instances migrated on' + listdate[i] + 'are: ' + no_of_inst; alert("Instances migrated on" + d + "are: " + no_of_inst); } }); } } <!DOCTYPE html> <html> <head> <title>Migration Status</title> <!--<link rel="stylesheet" href="styles.css">--> <div> <h3> M I G R A T I O N - S T A T U S </h3> </div> <meta charset="utf-8"> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.208.0.min.js"></script> </head> <body> <p>Select Filters to get your ec2 graph :</p> <form> <div class = "css-grid1"> <label> Launch-time: </label> </div> <div class = "css-inlineblock1"> <label for="fromdate">From Date:</label> <input type="date" id="fromdate" name="fromdate" min="2017-01-01"> <label for="todate">To Date:</label> <input type="date" id="todate" name="todate"> </div> <div class = "css-button"> <input type="submit" id="sbmt" onclick="applyFilters()"> </div> <div id="demo1"></div> <div id="demo2"></div> <div id="demo3"></div> <div id="demo4"></div> <div id="demo5"></div> <div id="demo6"></div> <div id="demo7"></div> <div id="demo8"></div> </form> <script> </script> </body> </html>
Split large block of text into individual spans with individual ids
PLEASE DO NOT MARK THIS AS DUPLICATE! THIS IS THE ONLY PURE JAVASCRIPT APPROACH WITH INDIVIDUAL ID'S How do I split a large block of text into individual spans with id's that go like this: <span class="word" id="word0">Breaking </span> <span class="word" id="word1">News. </span> <span class="word" id="word2">Spring </span> <span class="word" id="word3">is </span> <span class="word" id="word4">here </span> <span class="word" id="word5">to </span> <span class="word" id="word6">stay. </span> If the input was "Breaking News. Spring is here to stay." I want to get the input from a specific div and output it into the same div. Please do not use jquery for this. EDIT: Thanks to Scott Marcus, he gave me this code: /* hw3a.js */ // your solution here var button = document.getElementById('divideTranscript'); button.onclick = spanify(); var s = document.getElementById('transcriptText').innerHTML; function spanify() { var arry = s.split(" "); var arry = s.split(/\s+/); // This will split on any group of whitespaces var output = ""; var len = arry.length; for(var i = 0; i < len; ++i) { output += "<span class='word' id='word" + i + "'>" + arry[i] + "</span>" ; } s.innerHTML = output; } But it does not work?
var s = "Breaking News. Spring is here to stay."; var arry = s.split(" "); // This will split on all single whitespaces var arry = s.split(/\s+/); // This will split on any group of whitespaces var output = ""; var len = arry.length; for(var i = 0; i < len; ++i){ output += "<span id='word" + i + "'>" + arry[i] + "</span>" ; } alert(output); // Or, to be more core DOM compliant var d = document.createElement("div"); for(var i = 0; i < len; ++i){ var sp = document.createElement("span"); sp.setAttribute("id", "word" + i); sp.textContent = arry[i]; d.appendChild(sp); } alert(d.innerHTML);
Object property sent from HTML input "undefined"
I'm beginner in coding. I've tried to find similar problem on SO but with no proper result. I'm writting a code where HTML form sends its value to an object's property, then I want to print it in document using innerHTML method. I save object in array so then I can manipulate them. Some problems appears when I add one more dimension to my array (arr[i][j] in code below - 2nd dimension will be needed further) - then object's properties change to "undefined" when printed. What should I do to get access to object's properties in array's 2nd dimension (using JS only)? This is my JS code: var pro = 0; var ctg = 1; var arr = new Array(ctg); arr[0] = new Array(pro) function AddProduct() { var n = document.getElementById('name').value; var p = document.getElementById('price').value; pro++; for (i = arr[0].length; i < pro; i++) { arr[0].push([{ name: n, price: p }]); } var content = ''; for (i = 0; i < arr.length; i++) { for (j in arr[i]) { content += arr[i][j].name + ' price is ' + arr[i][j].price + '<br>'; } } document.getElementById('p').innerHTML = content; }; and HTML in body: <p id="p"></p> <input type="text" id="name" placeholder="name"> <br> <input type="text" id="price" placeholder="price"> <br> <input type="button" value="OK" onclick=A ddProduct()>
Try substituting onclick="AddProduct()" for onclick=A ddProduct() at html; and add [0] at content += arr[i][j][0].name + ' price is ' + arr[i][j][0].price + '<br>'; for content += arr[i][j].name + ' price is ' + arr[i][j].price + '<br>'; as you pushed an array containing an object to arr at first for loop. To reference the index of the array, use bracket notation to retrieve object at index 0 of array in arr var pro = 0; var ctg = 1; var arr = new Array(ctg); arr[0] = new Array(pro) function AddProduct() { var n = document.getElementById('name').value; var p = document.getElementById('price').value; pro++; for (i = arr[0].length; i < pro; i++) { arr[0].push([{ name: n, price: p }]); } var content = ''; for (i = 0; i < arr.length; i++) { for (j in arr[i]) { content += arr[i][j][0].name + ' price is ' + arr[i][j][0].price + '<br>'; } } document.getElementById('p').innerHTML = content; }; <p id="p"></p> <input type="text" id="name" placeholder="name"> <br> <input type="text" id="price" placeholder="price"> <br> <input type="button" value="OK" onclick="AddProduct()">
Creating and Adding content dynamically
I'm creating some ul and span tags dynamically. Now, I'm trying to add content dynamically as well through a click function. The tags gets created inside a ul but the content doesn't get inserted. Here is the code for it: <div class="main"></div> <div class="content-list"><ul class="information"> </ul></div> Here's the Javascript with the function and the listener: var $contentHandler = $(".content-list"); var $mainHandler = $(".main"); var $infoHandler = $(".information"); var circleCounter = 1; $mainHandler.click(function() { var htmlString = "<li class='" + circleCounter + "'> <span class='circle-color'> var color = <div class='circle-color-input' contentEditable autocorrect='off'> type a color</div> ; </span> <br> <span class='circle-radius'> This is supposed to change </span> <br> <span class='circle'> This is supposed to change </span> </li>" $infoHandler.append(htmlString); updateList(); circleCounter++; }); function updateList() { var listItems = $('.information').find('li#' + circleCounter); var len = circleCounter; for (var i = 0; i < len; i++) { //We create one reference. This makes looking for one element more effective. Unless we need to search for a particular element var currentItem = circles[i]; var updateStringRadius = "var radius = " + circleCounter + ";"; var updateStringCircle = "circle (" + circleCounter + " ," + circleCounter + ", radius)"; //This is the div Item for the particular div of each element var divItem = $(listItems[i]); var radiusItem = divItem.find("span.circle-radius"); var circleItem = divItem.find("span.circle"); radiusItem.text(updateStringRadius); circleItem.text(updateStringCircle); // divItem.text(updateString); var $circleRadiusHandler = $(".circle-radius"); } } Any suggestions in how to make it work. Here's a JSFiddle for that: http://jsfiddle.net/mauricioSanchez/wL6Np/1/ Thank you kindly,
You just need to change: var listItems = $('.information').find('li#' + circleCounter);//this searches by id //To: var listItems = $('.information').find('li.' + circleCounter);//this searches by class` //And remove: var currentItem = circles[i];
Why are you trying to edit your HTML after you've defined it? Why not use a template like this: var listItemClass = 'someclass', typeOfColor = 'somecolor', radiusOne = 'someradius', radiusTwo = 'anotherradius'; var listItem = "<li class='{0}'> \ <span class='circle-color'> var color = \ <div class='circle-color-input' contentEditable autocorrect='off'> {1}</div> ; \ </span> \ <br> \ <span class='circle-radius'>{2}</span> \ <br> \ <span class='circle'>{3}</span> \ </li>"; listItem.format(listItemClass, typeOfColor, radiusOne, radiusTwo); With the following format definition: String.prototype.format = String.prototype.f = function () { var s = this, i = arguments.length; while (i--) { s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]); } return s; }; This way, you don't have to worry about finding certain elements within your predefined structure after the fact. You're just replacing certain parts with whatever you specify.
Displaying Javascript Array in pre-coded HTML?
I need to display a list of 100+ football player numbers, names, weight, age, and heights. I would rather not copy/paste the same exact div I have set up and change them manually. I was wondering if there is a way to display each set of data in the html layout I already coded? The only thing I can find on google is Javascript generating it's own table. Here is an example: Here's the array: var playerArray = [ ["#25","Player1", "Weight1", "Height1", "Age1", "Position1"], ["#99","Player2", "Weight2", "Height2", "Age2", "Position2"], ["#77","Player3", "Weight3", "Height3", "Age3", "Position3"], ["#63","Player4", "Weight4", "Height4", "Age4", "Position4"], ["#43","Player5", "Weight5", "Height5", "Age5", "Position5"], ]; and here is my html where I want the data displayed: <div class="rosterlist"> <div class="p_name">[[NUMBER]] <span class="light_text2">/ [[NAME]]</span></div> <div class="roster_line_2"><div class="p_pos">[[POSITION]]</div><div class="p_height">[[HEIGHT]]</div><div class="p_grade">[[AGE]]</div><div class="p_weight">[[WEIGHT]]</div></div> </div> If it's not possible, just let me know and I'll get to my copying and pasting:(
This is best solved through data binding and templating. I recommend using a template based framework like KnockoutJS. This will give you the ability to specify a single entry that gets repeated for each entry Link: http://knockoutjs.com/
As Stano states, this is straight-forward to do without a library: var i, k, html = '', line = ''; var template = ''+ '<div class="rosterlist">' + '<div class="p_name">[[0]] <span class="light_text2">/ [[1]]</span></div>'+ '<div class="roster_line_2">'+ '<div class="p_pos">[[5]]</div>'+ '<div class="p_height">[[3]]</div>'+ '<div class="p_grade">[[4]]</div>'+ '<div class="p_weight">[[2]]</div>'+ '</div>'+ '</div>'+ ''; var data = [ ["#25","Player1", "Weight1", "Height1", "Age1", "Position1"], ["#99","Player2", "Weight2", "Height2", "Age2", "Position2"], ["#77","Player3", "Weight3", "Height3", "Age3", "Position3"], ["#63","Player4", "Weight4", "Height4", "Age4", "Position4"], ["#43","Player5", "Weight5", "Height5", "Age5", "Position5"], ]; for( i=0; i<data.length; i++ ) { line = template; for( k=0; k<data[i].length; k++ ) { line = line.replace('[['+k+']]', data[i][k]); } html += line; } document.getElementById('output').innerHTML = html; And in your markup: <div id="output"></div>
I'm personally a fan of Handlebars Here's a fiddle http://jsfiddle.net/BZ2nZ/ the HTML: <div id="container"></div> <script type="text/x-handlebars-template" id="rosterlistTemplate"> <div class="rosterlist"> {{#each this}} <div class="p_name">{{number}} <span class="light_text2">/ {{name}}</span> </div> <div class="roster_line_2"> <div class="p_pos">{{position}}</div> <div class="p_height">{{height}}</div> <div class="p_grade">{{age}}</div> <div class="p_weight">{{weight}}</div> </div> {{/each}} </div> </script> The data: var playerArray = [ ["#25","Player1", "Weight1", "Height1", "Age1", "Position1"], ["#99","Player2", "Weight2", "Height2", "Age2", "Position2"], ["#77","Player3", "Weight3", "Height3", "Age3", "Position3"], ["#63","Player4", "Weight4", "Height4", "Age4", "Position4"], ["#43","Player5", "Weight5", "Height5", "Age5", "Position5"], ]; Convert the data: var data = _(playerArray).map(function(playerInfo){ return _.object(['number','name','weight', 'height', 'age', 'position'], playerInfo); }); Putting the template to use : var template = Handlebars.compile($('#rosterlistTemplate').html()); $('#container').html(template(data)); I'm using underscore to convert the format of the data you have into something like this [ {number: xx, name: xx, weight: xx, height: xx, age: xx, position: xx}, {number: xx, name: xx, weight: xx, height: xx, age: xx, position: xx}, {number: xx, name: xx, weight: xx, height: xx, age: xx, position: xx}, ] If you can get the json in that format then you don't need underscore and can skip the 'convert data' step altogether.
Working jsFiddle Demo JavaScript <script> var playerArray = [ ["#25","Player1", "Weight1", "Height1", "Age1", "Position1"], ["#99","Player2", "Weight2", "Height2", "Age2", "Position2"], ["#77","Player3", "Weight3", "Height3", "Age3", "Position3"], ["#63","Player4", "Weight4", "Height4", "Age4", "Position4"], ["#43","Player5", "Weight5", "Height5", "Age5", "Position5"], ]; window.onload = function () { var template = document.getElementById('template').innerHTML; var list = document.getElementById('list'); for (var i = 0, l = playerArray.length; i < l; i++) { var values = { 'NUMBER': playerArray[i][0], 'NAME': playerArray[i][1], 'WEIGHT': playerArray[i][2], 'HEIGHT': playerArray[i][3], 'AGE': playerArray[i][4], 'POSITION': playerArray[i][5], }; var t = template; for (var p in values) { t = t.replace('[[' + p + ']]', values[p]); } list.innerHTML += t; } }; </script> HTML <div id="list"></div> <script id="template" type="text/html"> <div class="rosterlist"> <div class="p_name">[[NUMBER]] <span class="light_text2">/ [[NAME]]</span></div> <div class="roster_line_2"><div class="p_pos">[[POSITION]]</div><div class="p_height">[[HEIGHT]]</div><div class="p_grade">[[AGE]]</div><div class="p_weight">[[WEIGHT]]</div></div> </div> </script>
You can traverse the array like this: var str = ''; var len = playerArray.length; for (var i = 0; i < len; i++) { str += '<div class="p_name">' + playerArray[i][0] + '/ <span class="light_text2">' + playerArray[i][1] + '</span> \ </div> \ <div class="roster_line_2"> \ <div class="p_pos">' + playerArray[i][5] + '</div> \ <div class="p_height">' + playerArray[i][3] + '</div> \ <div class="p_grade">' + playerArray[i][4] + '</div> \ <div class="p_weight">' + playerArray[i][2] + '</div> \ </div>'; } document.getElementById('rosterlist').innerHTML = str; Full javascript code here: http://jsfiddle.net/VuKmv/ (compatible also with IE6+)