Jquery each loop doesn't display JSON item's properties - javascript

Edited2: Here is a pic of how one object looks like. All fields for all objects are filled.
Edited: So the problem appears to be the each loop. I console.logged data and it showed it in an array style. But for some reason, when i try to print the object's age, f.ex., it shows up as undefined.
I am doing a small script for displaying information from a json-file with jquery and ajax. I got the ajax part working (I think) but I can't get my function to print the JSON object data.
So I am trying to display JSON object's with Jquery but it doesn't do anything. The ready function prints out done and complete.
$(document).ready(function(){
$.ajax({
url: "file.json",
cache: false
}).done(function(data) {
console.log("done");
showData(data);
}).fail(function() {
console.log("error");
}).always(function() {
console.log("complete");
});
});
function showData(data) {
$.each(data.cats, function(index, kitty) {
var div = $("<div></div>");
div.addClass("catContainer");
var image = $("<img></img>");
image.addClass("catImage");
image.src="kitty.image";
var header = $("<p></p>").text(kitty.color);
header.addClass("header");
var age = $("<p></p>").text(kitty.age);
var text = $("<p></p>").text(kitty.text);
text.addClass("text");
var price = $("<p></p>").text(kitty.price);
div.append(image,header,size,text,price);
$("div#cats").append(div);
});
}
I also tried this loop but it prints 'undefined' to the div:
$(data).each(function(i, kitty) {
$('#cats').append(kitty.price);
// I am sorry, I am noob. Hope this post is according to the instructions.

One issue is with your image.src. When you set it to "kitty.image", this would literally assign that string. So instead of:
image.src = "kitty.image",
Use:
image.attr("src", kitty.image);
Or:
image[0].src = kitty.image
The latter here, since image is a jQuery Object, would not have src as an index. So we can call image[0] to get the HTML Element, that we can then assign the src.
Consider the following.
$(function() {
function showData(d, o) {
$.each(d, function(index, kitty) {
console.log("Adding Kitty", kitty);
var div = $("<div>", {
class: "catContainer"
}).appendTo(o);
$("<img>", {
class: "catImage",
src: kitty.image
}).appendTo(div);
$("<p>", {
class: "header"
}).html(kitty.color).appendTo(div);
$("<p>").html(kitty.age).appendTo(div);
$("<p>", {
class: "text"
}).html(kitty.text).appendTo(div);
$("<p>").html(kitty.price).appendTo(div);
});
}
$.ajax({
url: "file.json",
cache: false,
success: function(data) {
showData(data.cats, "#cats");
console.log("Success");
},
error: function(x, e, n) {
console.log("Error", x, e, n);
}
});
});
Based on your post, data is an Object. data.cats is an Array of Objects. So we will iterate the Array with $.each() using data.cats. I also pass in the target object ID. .appendTo() accepts a few items:
A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter.
See More: https://api.jquery.com/appendto/
It is then just a matter of creating each of the elements. With the $("<div>"), jQuery will handle wrapping the element for us. We can also pass in an Object with the attributes, like class. We can chain to the jQuery Object that is the result and would advise using .html() versus .text(), yet there is nothing wrong with doing either.

Related

How to use jQuery ajax to check if file exists in JS array?

I have an array urlResult which collects the href attribute of all a elements on a component. Looks like:
All I need to do is use jQuery $.ajax() method to check against those URL's and in each callback do something if there is success or failure. So I was thinking of something like:
$.ajax({
url: urlResult[i] // somehow use dynamic variable?
type:'HEAD',
error: function()
{
//file not exists
},
success: function()
{
//file exists
}
});
I just need some guidance on how to dynamically include urlResult variable and pass each index to url property in ajax call.
You can use .forEach() to loop over the array of hrefs, and then execute your code inside the loop
const urlResult = ['www.google.com', 'www.test.com', 'www.demo.com', 'www.aaaa.net'];
urlResult.forEach((href) => {
$.ajax({
url: href,
type: 'HEAD',
error: function() {
console.log('HREF was ' + href);
console.log('error');
},
success: function() {
console.log('HREF was ' + href);
console.log('success');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Consider the following code.
$(function() {
function checkFile(u) {
var result = false;
$.ajax({
url: u
type: "HEAD",
success: function() {
result = true;
}
});
return result;
}
$.each(urlResult, function(i, v) {
if (checkFile(v)) {
// File exists, do the needful
}
});
});
Remember that success is only called when HTTP Status is 200. I used $.each() to iterate over the Array.
The $.each() function is not the same as $(selector).each(), which is used to iterate, exclusively, over a jQuery object. The $.each() function can be used to iterate over any collection, whether it is an object or an array. In the case of an array, the callback is passed an array index and a corresponding array value each time.
See More:
https://api.jquery.com/jquery.ajax/
https://api.jquery.com/jQuery.each/

Passing key-value pair jquery array into .NET MVC action

I have an jquery key-value pair array as following:
The array is filled when check-boxes are checked
If a checkbox is unchecked, item will be removed from there
The code for that part is:
$(document).on('click', '.chkItem', function () {
if ($(this).is(':checked')) {
product_ids[$(this).attr('id')] = "Checked";
} else {
delete product_ids[$(this).attr('id')];
}
});
This works fine, let's head onto the next part. Now I'm trying to send all these ID's from my view into a controller "Analyze" and action "Index", which looks as following:
$(".btnAnalyze").click(function () {
if (jQuery.isEmptyObject(product_ids) == true) {
alert("Array is empty");
}
else {
var postData = { values: product_ids };
$.ajax({
type: "POST",
url: "/Analyze/Index",
data: postData,
success: function (data) {
alert(data.Result);
},
dataType: "json",
traditional: true
});
}
});
And my action looks like following:
public ActionResult Index(List<string> values)
{
string id2= "";
foreach (var id in values)
{
id2= id;
}
// I'm trying to fetch the ID values here that I added into the array, but I'm not sure how...
}
With this current method the contents of List values is
"[object Object]"
which is not what I want.. I need all of the ID's sorted out nicely into the list as I send them to the Action Index...
Can someone help me out with this???
You're using an object, not an array, and it is thus saying that it's an object. You have two choices:
Use an actual array:
var product_ids = [];
$(document).on('click', '.chkItem', function () {
if ($(this).is(':checked')) {
product_ids.push($(this).attr('id'));
} else {
product_ids.splice(product_ids.indexOf($(this).attr('id')), 1);
}
});
Continue using an object and use Object.keys to get just the property names (which are the IDs in your code):
var postData = { values: Object.keys(product_ids) };
Personally, I like #1 because it's more explicit that you're capturing the ids of the checked checkboxes, and the values of the object's properties is always "Checked" rather than anything meaningful, but hey, JavaScripts' flexible like that :).
Use console.log(data.Result) to debug instead of alert(data.Result), because alert(data.Result) stringifies your variable to [object Object]. To open up console press F12

JavaScript - Array values blank

I have a unique challenge:
While on URL1(random wikipedia page), make an ajax request to URL2(100 most common words wikipedia page), create array from returned data to be used later.
I have to run this from the console while on "URL1"
example:
Navigate to URL1
Open Console
paste code
hit enter
So far I have been able to get very close with the following:
$.ajax({
url: 'https://en.wikipedia.org/wiki/Most_common_words_in_English',
type: 'GET',
dataType: 'html',
success: function(data) {
Names = $.map($(data).find('.wikitable tr'), function() {
return $(this).find('td:last').text()});
console.log(Names);
}
});
But I'm getting blank values in my array.
While on URL2(link in the ajax request) the following code works perfect
var Names = $('.wikitable tr').map(function() {
return $(this).find('td:last').text() }).get(); console.log(Names);
I was gettin errors using this exact code because of the .get, after removing it, I got an array with the proper amount of elements, but they were all blank.
Thanks
Your logic is right, you are just using the wrong functions. $.map and $().map are different function with different contexts and different arguments.
Your problem should be solved if you use the correct map function. Change
success: function(data) {
Names = $.map($(data).find('.wikitable tr'), function() {
return $(this).find('td:last').text();
});
console.log(Names);
}
to
success: function(data) {
Names = $(data).find('.wikitable tr').map(function() {
return $(this).find('td:last').text();
});
console.log(Names);
}
In the second form of map, the this keyword is set to DOM element.
I also noticed that would code is returning 105 texts instead of the 100 words in the table, as it is picking the table headers too. Another cool trick of .map is that if you return null, it will not include the value in the result. Therefore, you could something like
Names = $(data).find('.wikitable tr').map(function() {
return $(this).find('td:last').text() || null;
});
as a blank string evaluates to false so the return will return null instead of ''. Or, you could just make your selector more specific, such as:
Names = $(data).find('.wikitable tr td:odd').map(function() {
return $(this).text();
});
Could you also Inspect via F12, if any error is thrown.
XMLHttpRequest cannot load https://en.wikipedia.org/wiki/Most_common_words_in_English. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Just use the Js map to iterate over Jquery Objects(Html element Object)
$(data).find('.wikitable tr').map(function() {
return $(this).find('td:last').text();
JQuery map Works only on primitives Array not on object
$.map($(data).find('.wikitable tr'), function() {
return $(this).find('td:last').text();
});

How do I add returned JavaScript array items to specific textboxes

I called a URL using AJAX using the following code below and it returned 2 items in an array in this format ["item1", "item2"]
function getbook()
{
$.ajax({
type: "POST",
url: "/Home/getBooked",
data: { "bookNumber": mobile },
success: function(succ) { // I need to add the items in succ to some text boxes as shown below
$.each(succ, function (index, element) {
$('#tb1').val(element);
$('#tb2').val(element);
});
},
error: function(err) {
alert("An error is thrown");
}
});
}
But the issue is that only the last item in the succ array is shown in both the textboxes. When I used the alert function to display the contents of succ, it displayed both the items. Clearly i'm missing something. I'll be glad if anyone could help.
The problem is you are setting the value in each iteration. Try like following.
success: function (succ) {
$('#tb1').val(succ[0]);
$('#tb2').val(succ[1]);
}
if the IDs of textbox is kind of sequence then we can resolve like bellow:
$.each(succ, function (index, element) {
$('#tb'+ (index + 1)).val(element);
});

dynamically creating text boxes after loop through javascript object

I have a javascript that sends some info to through an ajax request to the server and receives some data as Questions and their's ID's as a json array.
This is what the response json array i receive from the server looks like:
[
{
"ID":"1",
"question":"Write a function called addNum. "
},
{
"ID":"3",
"question":"Write a function called sumDouble "
}
]
And this is javascript:
$(document).ready(function(){
$("form#input_qnumber").submit(function() {
var questions = $('#questions').attr('value'); // written question
var quizname = $('#quizname').attr('value');
if (questions) { // values are not empty
$.ajax({
type: "POST",
url: "https://xxxx",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "application/json",
data: 'questions='+questions+'&quizname='+quizname,
success: function (data)
{
var JSONObject = JSON.parse(data);
for (var key in JSONObject) {
if (JSONObject.hasOwnProperty(key)) {
console.log(JSONObject[key]["ID"] + ", " + JSONObject[key]["question"]);
}
}
}
});
}
else {
$('div#createquizresp').text("Enter question ID's separated by a comma to be included in the quiz");
$('div#createquizresp').addClass("error");
} // else
$('div#createquizresp').fadeIn();
return false;
});
});
As you see, I can parse the response json into a javascript object array, loop through it and dump the contents in console. What I would like though would be to create textarea element, give its id attribute the 'ID' key from my array and label it with the corresponding question key from the array. After this I can just append the element to a div inside my html. But I am not really sure how to do it or if its even possible. Please HALP.
if you want also a label element;
for (var key in JSONObject) {
if (JSONObject.hasOwnProperty(key)) {
$('<label>')
.attr('for', JSONObject[key]["ID"])
.html(JSONObject[key]["question"])
.appendTo('wherever_you_want');
$('<textarea>')
.attr('id', JSONObject[key]["ID"])
.appendTo('wherever_you_want');
}
}
create dynamic elements input and label and then append these elements to the parent div or to the body what ever suits your requirement.
DEMO :https://jsfiddle.net/ew4mqhow/3/
<div id ="display"></div>
<script>
var textbox = document.createElement('input');
textbox.setAttribute("id", JSONObject[key]["ID"]);
var labell = document.createElement('label');
labell.setAttribute("for",JSONObject[key]["question"]);
labell.innerHTML = JSONObject[key]["question"];
document.getElementById('display').appendChild(textbox);
document.getElementById('display').appendChild(labell);
</script>
Answer by keune is perfect. One suggestion, tho - do add a prefix to foreign ID's. Just to be on safe side on case You'll assign ID's to other types of elements (ie. answers), too.
for (var key in JSONObject) {
if (JSONObject.hasOwnProperty(key)) {
$('#quizquestions')
.append($('<label>')
.attr('for', 'Q' + JSONObject[key]["ID"])
.html(JSONObject[key]["question"]))
.append($('<textarea>')
.attr('id', 'Q' + JSONObject[key]["ID"]))
}
}

Categories