Using Ajax to loop through nested Array to retrieve data - javascript

Good Morning, using ajax call I am trying to return the values of a nested json array, I was successful to pull the data except for the nested array "booking_status". When I try loop through the 'booking_status', I git the value [object Object],[object Object],[object Object] . If I try to specify a value for example item.booking_status.status I get this undefined.
This is my nested array
[
{
"id": 1,
"item_name": "Misrry",
"author": "Stephen King",
"booking_status": [
{
"check_in": "2021-09-22T08:27:00+04:00",
"check_out": "2021-09-23T08:27:00+04:00",
"status": "Currently Booked"
},
{
"check_in": "2021-09-25T08:37:00+04:00",
"check_out": "2021-09-26T08:37:00+04:00",
"status": "Currently Free"
},
{
"check_in": "2021-09-27T08:37:00+04:00",
"check_out": "2021-09-28T08:37:00+04:00",
"status": "Currently Free"
}
]
{
"id": 2,
"item_name": "Rose Red",
"author": "Stephen King",
"booking_status": [
{
"check_in": "2021-09-22T08:27:00+04:00",
"check_out": "2021-09-23T08:27:00+04:00",
"status": "Currently Booked"
},
{
"check_in": "2021-09-25T08:37:00+04:00",
"check_out": "2021-09-26T08:37:00+04:00",
"status": "Currently Free"
}
]
}
]
and this is my script:
<script>
$(document).ready(function () {
$.ajax({
url: 'http://localhost:8000/',
dataType: 'JSON',
success: function (data) {
for (var i = 0; i < data.length; i++) {
$(document).ready(function () {
var content = ''
data.forEach(item => {
content += "<tr><td>"
+ item.item_name + "</td><td>"
+ item.author + "</td><td>" + item.booking_status
+ "</td></td></tr>"
})
$('#table_body').html(content);
})
}
}
});
});
</script>

You have a couple of mistakes in your code.
You're iterating over data twice. (for loop and data.forEach);
Remove the for loop, it's redundant.
booking_status is an array, so you're going to have to stringify it, or iterate over it somehow.
You don't need to nest $(document).ready. The inner calls can be removed.
$(document).ready(function() {
$.ajax({
url: 'http://localhost:8000/',
dataType: 'JSON',
success: function(data) {
var content = '';
data.forEach(item => {
content += "<tr><td>" +
item.item_name + "</td><td>" +
item.author + "</td><td>" + item.booking_status.map(s => s.status).join('<br/>') +
"</td></td></tr>";
});
$('#table_body').html(content);
});
});
});

Related

How to make a dropdown of the data receive from ajax response as array of objects

I want to make a dropdown in my table which is populated with the dynamic data coming from ajax response and append to the table.
My postman collection looks like this.
{
"createdDate": "2022-04-06T11:42:37.360Z",
"enabled": true,
"_id": "62502b868daa3b1cdbdc98e8",
"CNIC": "40740c7d9f3a11d93e76af7f2f60887a",
"employeeID": "LE44337",
"fName": "HUSNAIN",
"company": "6249fdf91399dc7a14173dcd",
"fatherName": "husnain",
"motherName": "momutaz",
"spouse": "no spouse",
"children": [{
"_id": "62502b868daa3b1cdbdc98e9",
"name": "hunsian",
"age": 23232
}, {
"_id": "62502b868daa3b1cdbdc98ea",
"name": "hunsian",
"age": 12121
}, {
"_id": "62502b868daa3b1cdbdc98eb",
"name": "momin",
"age": 2323
}
}
And below is my ajax response code in which I am appending the data into table.
success : function(response){
var trHTML = '';
$.each(response.doc, function (i, item) {
trHTML += '<tr><td>' + item.fName + '</td><td>' + item.CNIC + '</td><td>' + item.spouse + '</td><td>'+ item.fatherName + '</td><td>' + item.motherName +'</td><td>'+ item.employeeID +'</td><td>' + item.children.map(({name, age}) => `Name: ${name} Age: ${age}`).join(' || ') +'</td></tr>';
});
$('#records_table').append(trHTML);
}
The itme.children name , age I want to make a dropdown of it into table so it looks good.
If you mean a dropdown like a select menĂº, this should do the job
trHTML += `... <td>
<select>
<option selected disabled>Click me</option>` +
item.children.map(({name + age}) => `<option>Name: ${name}, Age: ${age}</option>`).join('') +
`</select></td>`;

I can fetch one word, but not the other one, how can this be?

I am making a CMS with an edit button. When you click the edit button it should everything from the JSON file back to the CMS side so you can actually edit.
However when I try to fetch my word I can only fetch one while I have 2 word in my JSON.
This is how my JSON looks like:
{
"main_object": {
"id": "new",
"getExerciseTitle": "TestToConfirm",
"language": "nl_NL",
"application": "lettergrepen",
"main_object": {
"title": "TestToConfirm",
"language": "nl_NL",
"exercises": [{
"word": "huishoudelijk",
"syllables": [
"huis",
"houdelijk",
"",
""
]
},
{
"word": "Kleedt u zich maar uit.",
"syllables": [
"Kleed",
"u",
"zich",
"uit"
]
}
]
},
"dataType": "json"
}
}
This is how I am trying to loop through my word so I can fetch it all. I do have to note that I am going to fetch the syllables aswell and i'm not entirely sure if it's bad to create 2 different loops to fetch the data. Or is it recommended to do it both in 1 loop?
$(document).ready(function() {
$.getJSON('json_files/jsonData_' + ID + '.json', function(json) {
// console.log(json);
var exercisetitle = json.main_object.getExerciseTitle;
// console.log(exercisetitle);
$("#getExerciseTitle").val(exercisetitle);
var exercise = json.main_object.main_object.exercises;
$.map(exercise, function(exercise, i) {
var myindex = 1;
$("#addOpdracht").click();
$(".exerciseGetWordInput_" + myindex).val(exercise.word)
myindex++;
});
});
});
The code of exerciseGetWordInput_:
The #addOpdracht is just a button that creates new exercise blocks. I don't think that has much to do with how to loop or the possible cause of my app failing.
function getWordInput(id, cValue) {
cValue = cValue || '';
var wInput = $('<input/>', {
'class': 'exerciseGetWordInput_' + id + ' form-group form-control ExerciseGetWordInput',
'type': 'text',
'name': 'question_takeAudio_exerciseWord[' + exerciseAudioInput + ']',
'placeholder': 'Exercise',
'id': 'exerciseGetWordInput',
'required': true
});
return wInput;
}
Move var myindex = 1 outside the loop
var myindex = 1;
$.map(exercise, function(exercise, i) {
$("#addOpdracht").click();
$(".exerciseGetWordInput_" + myindex).val(exercise.word)
myindex++;
});
OR you can also avoid use of extra variable like following and use each instead
$.each(exercise, function(exercise, i) {
$("#addOpdracht").click();
$(".exerciseGetWordInput_" + i).val(exercise.word) // starts with 0
});
Use each
use IDs
execute the function you would normally execute on click.
var data = {
"main_object": {
"id": "new",
"getExerciseTitle": "TestToConfirm",
"language": "nl_NL",
"application": "lettergrepen",
"main_object": {
"title": "TestToConfirm",
"language": "nl_NL",
"exercises": [{
"word": "huishoudelijk",
"syllables": [
"huis",
"houdelijk",
"",
""
]
},
{
"word": "Kleedt u zich maar uit.",
"syllables": [
"Kleed",
"u",
"zich",
"uit"
]
}
]
}
}
}
$.each(data.main_object.main_object.exercises, function(_,exercise) {
addOpdracht(exercise)
});
function addOpdracht(exercise) {
var $container = $("#exerciseContainer"),
count = $container.length,
$div = $("<div/>").addClass("exerciseDiv"),
$input = $("<input/>", {
type: "text",
id: "exerciseGetWordInput_" + count,
value: exercise.word
})
$div.append($input);
$container.append($div);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="exerciseContainer"></div>

How to link a JSON generated list to display the content of a different JSON file

I'm calling a JSON file (sections.json), and then accessing the array sections, looping through every item and appending the name value to a li. I wish to give this li a link (or click event) to display the articles names of the corresponding section on .sectionArticles. To access the articles of a specific section, I have to access a different JSON file (sections/{section id}/articles.json). I'm clueless on this last part... could someone point me out in the right direction?
Here is my current code so far:
$(function() {
// URLs
var zendeskUrl = 'https://myhelpcenter.zendesk.com/'
var sectionsUrl = zendeskUrl+'api/v2/help_center/pt-br/sections.json';
var articlesUrl = zendeskUrl+'api/v2/help_center/pt-br/articles.json?per_page=100';
$.ajax({
type: 'GET',
url: sectionsUrl,
success: function(data) {
data.sections.forEach(function(section) {
$('.sectionsList').append('<li class="sectionName">' + section.name + '</li>');
})
},
error: function() {
console.log("Error: sectionsUrl");
}
})
$.ajax({
type: 'GET',
url: articlesUrl,
success: function(data) {
data.articles.forEach(function(article) {
if (article.promoted == true) {
$('.promotedList').append('<li class="promotedName">' + article.name + '</li>');
}
})
},
error: function() {
console.log("Error: articlesUrl");
}
})
})
JSOM Sample:
List ALL Sections: /api/v2/help_center/sections.json
{
"sections": [
{
"id": 115001417087,
"url": "/api/v2/help_center/sections/115001417087.json",
"html_url": "/hc/sections/115001417087",
"category_id": 115000835587,
"position": 0,
"sorting": "manual",
"created_at": "2017-03-22T14:29:48Z",
"updated_at": "2017-06-13T20:01:01Z",
"name": "Section 1",
"description": "",
"locale": "",
"source_locale": "",
"outdated": false
}
],
"page": 1,
"previous_page": null,
"next_page": null,
"per_page": 30,
"page_count": 1,
"count": 8,
"sort_by": "position",
"sort_order": "asc"
}
List ALL Articles from Section {id}: /api/v2/help_center/sections/{id}/articles.json */
{
"count": 9,
"next_page": null,
"page": 1,
"page_count": 1,
"per_page": 30,
"previous_page": null,
"articles": [
{
"id": 115008623727,
"url": "/api/v2/help_center/articles/115008623727.json",
"html_url": "/hc/articles/115008623727",
"author_id": 20423232608,
"comments_disabled": true,
"draft": false,
"promoted": false,
"position": 0,
"vote_sum": 0,
"vote_count": 0,
"section_id": 115001417087,
"created_at": "2017-06-13T19:46:17Z",
"updated_at": "2017-06-13T19:59:28Z",
"name": "Some name",
"title": "Some title",
"body": "Some HTML",
"source_locale": "",
"locale": "",
"outdated": false,
"outdated_locales": [],
"label_names": []
}
],
"sort_by": "position",
"sort_order": "asc"
}
I don't know if I understood the question the right way, but I assume you load the section list in the beginning and then want to load articles only when requested.
Therefore I'd first store the section id in the section list, so I can reuse it later on.
$.ajax({
type: 'GET',
url: sectionsUrl,
success: function(data) {
data.sections.forEach(function(section) {
$('.sectionsList').append('<li class="sectionName" data-section-id="' + section.id + '">' + section.name + '</li>');
})
},
error: function() {
console.log("Error: sectionsUrl");
}
})
With .on('click'), you already went into the right direction but since the sections are generated after event binding took place, you need event delegation to react on your click.
you can read more on this here: https://learn.jquery.com/events/event-delegation/
Additionally, I added the empty() call to clear the article list. If there are previous results, you can move that line into the ajax success function. If you want to keep the old list as long as no valid response has been returned, in terms of usability, I wouldn't. Keeping it doesn't show the user that something is happening. They might wait a moment and click again and again and again and so on. Better rework the error function to show something in the list instead of the console.log.
$(".sectionsList").on("click", ".sectionName", function(){
clickedSectionId = $(this).data("sectionId");
$('.promotedList').empty(); //clear list of previous results
articlesUrl = zendeskUrl + 'api/v2/help_center/' + clickedSectionId + '/articles.json?per_page=100';
$.ajax({
type: 'GET',
url: articlesUrl,
success: function(data) {
data.articles.forEach(function(article) {
if (article.promoted == true) {
$('.promotedList').append('<li class="promotedName">' + article.name + '</li>');
}
})
},
error: function() {
console.log("Error: articlesUrl");
}
});
});
I assume that your ajax calls are setup the way you need them. Just focus on storing the section id and binding the click function the correct way.

Select2.js: why is id the same as text on change for removed?

JSfiddle: http://jsfiddle.net/cjVSj/
I have a simple select2 with the range of possible tags set by the tags option and the preloaded tags set by values in the input field in the html.
When the on change event fires on the select2, the removed item seems to lose its id, reporting instead its text value.
To see the problem, adding a tag (e.g. west) correctly reports the added.id, but removing the existing east tags reports id = east, not 1356.
Any insight into how to gain access to the id of a tag upon removal?
HTML:
<script>
var tags = [{ "id": 1354, "text": "north", "restricted": false
}, {"id": 1355, "text": "south", "restricted": false
}, {"id": 1356, "text": "east", "restricted": false
}, {"id": 1357, "text": "west", "restricted": false
}];
</script>tags:
<input type="text" id="mytags" value="east" />
JS:
$(document).ready(function () {
$('#mytags').select2({
placeholder: 'Search',
allowClear: true,
minimumInputLength: 2,
multiple: true,
tags: tags,
tokenSeparators: [','],
});
$('#mytags').on("change", function (e) {
console.log("change " + JSON.stringify({
val: e.val,
added: e.added,
removed: e.removed
}));
if (e.added) {
alert('added: ' + e.added.text + ' id ' + e.added.id)
} else if (e.removed) {
alert('removed: ' + e.removed.text + ' id ' + e.removed.id)
}
});
});
There was an issue with your select2 declaration and syntax.
Further more, if you entered any other text, say "eas" or "test", your piece of code reflected that as it is. Check this scenario.
Updated fiddle: http://jsfiddle.net/ZBf5H/
To be specific, you did not give appropriate mapping to your tags. Please find how to access remote data in select 2 from here
The change of code is as below:
$(document).ready(function() {
var data=[{id:1354,text:'north',restricted:false},
{id:1356,text:'east',restricted:false},
{id:1357,text:'west',restricted:false},
{id:1355,text:'south',restricted:false}];
function format(item)
{ return item.text; }
$('#mytags').select2({
placeholder: 'Search',
allowClear: true,
minimumInputLength: 2,
multiple: true,
tags: tags,
tokenSeparators: [','],
data:{ results: data, text: 'text' },
formatSelection: format,
formatResult: format
});
Let me know if this works for you.
Ok... I've got a working solution, but I still don't exactly understand the difference between select2's tags and data options....
JSfiddle: http://jsfiddle.net/7e8Pa/
I'm initializing select2 with a list of all possible tags via the data option from an array, then selecting those for preloading: the initSelection function checks for ids in the and looks them up in the data array (the pre-stored one, not Select2's). Last, new tags may be added (the createSearchChoice does this). To hook this to my server, I'm just going to insert ajax calls where noted below in the on-change event handler (which gets called after createSearchChoice, and can overwrite the field values for the new object set in createSearchChoice).
JS:
function findWithAttr(array, attr, value) {
for (var i = 0; i < array.length; i += 1) {
if (array[i][attr] == value) {
return array[i];
}
}
}
$(document).ready(function () {
function format(item) {
return item.text;
}
$('#mytags').select2({
placeholder: 'Search',
minimumInputLength: 2,
multiple: true,
//tags: tags,
tokenSeparators: [','],
data: {
results: tags,
text: 'text'
},
initSelection: function (element, callback) {
var data = [];
$($('#mytags').val().split(",")).each(function (i) {
var o = findWithAttr(tags, 'id', this);
if (o) {
data.push({
id: o.id,
text: o.text
});
} else {
console.log("findWithAttr returned none; likely invalid id");
}
});
console.log("data = " + JSON.stringify(data));
callback(data);
},
createSearchChoice: function (term, data) {
console.log("create");
if ($(data).filter(function () {
return this.text.localeCompare(term) === 0;
}).length === 0) {
// call $.post() to add this term to the server, receive back id
// return {id:id, text:term}
// or detect this shiftiness and do it below in the on-change
return {
id: -1,
text: term
};
}
},
formatSelection: format,
formatResult: format
});
$('#mytags').on("change", function (e) {
console.log("change " + JSON.stringify({
val: e.val,
added: e.added,
removed: e.removed
}));
if (e.added) {
alert('added: ' + e.added.text + ' id ' + e.added.id);
//modifying the id here overrides what is assigned above in createSelection
e.added.id = 5;
} else if (e.removed) {
alert('removed: ' + e.removed.text + ' id ' + e.removed.id);
}
var selections = (JSON.stringify($('#mytags').select2('data')));
$('#selectedText').text(selections);
});
});
HTML:
<script>
var tags = [{
"id": 1354,
"text": "north",
"restricted": false
}, {
"id": 1355,
"text": "south",
"restricted": false
}, {
"id": 1356,
"text": "east",
"restricted": false
}, {
"id": 1357,
"text": "west",
"restricted": false
}];
</script>
<p>tags:
<input type="text" id="mytags" value="1355" style="width:80%" />
</p>
<p>Selected Options: <span id="selectedText"></span>
</p>
<p>Debug: <span id="debug"></span>
</p>

How to output data as HTML from JSON object using getJSON

Hello there I will try and keep this simple and short
I have a getJSON function that runs every 5 seconds. Now when I display the data using document.write function it dosent seem to want to update. The page is stuck in a loading loop. How can I get the data to display on my page? My JSON is fine but I will show you anyways.
<script type="text/javascript">
$.ajaxSetup ({
cache: false
});
setInterval(function(){ $.getJSON('names.json', function(data) {
for(i in data) {
document.write(data[i] + "<br/>");
}
});
},5000);
</script>
This is the JSON object
{
"one": "",
"two": "Beady little eyes",
"three": "Little birds pitch by my doorstep"
}
Don't actually use document.write. Once the page is loaded, that will erase the page. Use (jQuery's) DOM methods to manipulate the DOM.
$.getJSON('names.json', function(data){
for(var i in data){
$('#myDiv').append(data[i]);
}
});
I would recommend you use jQuery,
I used this to create a form from my json item, I hope this helps...
function jsonFormCreator(frmJSON)
{
var createdHTML = ""; var elementType, id;
console.log(JSON.stringify(frmJSON));
for(item in frmJSON)
{
formElement = frmJSON[item]; elementType = formElement.elementType; id = formElement.id;
if(elementType == "input")
{
createdHTML += "<input id='" + id +"'";
if(formElement.type == "checkbox")
{createdHTML += " type='" + formElement.type + "' checked='" + formElement.checked + "'";}
else{createdHTML += "type='" + formElement.type + "' value='" + formElement.value + "' onclick='" + formElement.onclick + "'";}
createdHTML += "/><br>"
}
else if(elementType == "textarea")
{createdHTML += "<textarea id='" + formElement.id + "' rows='" + formElement.rows + "' cols='" + formElement.cols + "' value='" + formElement.value + "'></textarea><br>";}
else if(elementType == "select")
{
var options = formElement.values;
createdHTML += "<select id='" + formElement.id+ "'>";
for(i = 0 ; i < options.length ; i++)
{createdHTML += "<option value='" + options[i][0] + "'>" + options[i][1] + "</option>";} //Adding each option
createdHTML+= "</select><br>";
}
}
console.log("Complete");console.log(createdHTML);
document.getElementById('mainContainer').innerHTML = createdHTML;//Adding to the DOM
}
And my JSON would look like this
{
"0": {
"elementType": "input",
"id": "frm1",
"type": "text",
"value": "form Liam",
"label": "Test Text Input"
},
"itemBTN": {
"elementType": "input",
"id": "frmAlert",
"type": "button",
"onclick" : "loader(homePage);",
"value": "Home Page",
"label": ""
},
"item2": {
"elementType": "textarea",
"id": "frm2",
"rows": 5,
"cols": 30,
"value": "helddddddddlo",
"label": "Test Textarea"
},
"item3": {
"elementType": "select",
"id": "frm3",
"values": [
[
"value1",
"Pick Me"
],
[
"value2",
"UserDis2"
],
[
"value3",
"UserDis3"
],
[
"value4",
"UserDis4"
],
[
"value5",
"UserDis5"
],
[
"value6",
"UserDis6"
]
],
"label": "Test Select"
},
"item4": {
"elementType": "input",
"id": "frm4",
"label": "Checkbox",
"type": "checkbox",
"checked": true
}
}
This code adds the form in to my div tag with the id mainContainer
I know its alot of code, but i hope it helps !
You want to render dom which will contain the data, then when you get the data update the dom.
As an exceedingly simple example, on your page have a container
<div id="one"></div>
and then in your ajax success handler
$("#one").text(json.one);
This uses jquery to grab the dom element with id "one", and update its text.

Categories