I have the following Microsoft Dynamics related XMLHttpRequest javascript function, and is encountering issue when attemtping to retrieve the entity attributes of the returned records.
The record managed to be created even though the conditions should have blocked it. It is likely that my following statement caused the issue:
var result1 = results.results[0];
alert("result1: " + result1.id); //Not displayed
function DisableInvalidRecordCreation(context) {
var saveEvent = context.getEventArgs();
var idNumber= Xrm.Page.getAttribute("IDNumber").getValue();
var category= Xrm.Page.getAttribute("Category").getValue();
var id = Xrm.Page.data.entity.getId();
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/ccc_cases?$select=IDNumber&$filter=IDNumber eq '" + idNumber+ "' and statecode eq 0", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\",odata.maxpagesize=1");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
if (results.value.length > 0 && id == "") {
alert(results.value.length); //Displayed as 1
var result1 = results.results[0];
alert("result1: " + result1.id); //Not displayed
for (var i = 0; i < results.entities.length; i++) {
var returned_category= results.entities[i]["Category"];
alert(returned_category); //Not displayed
if (category == 100000003 && returned_category!= 100000003)
{
alert("Invalid record");
saveEvent.preventDefault();
}
}
}
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
}
This is happening because in your get request you are selecting only IDNumber field and not the one you desire like Category
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/ccc_cases?$select=IDNumber&$filter=IDNumber eq '" + idNumber+ "' and statecode eq 0", false);
Also it should not be var result1 = results.results[0];
rather it should be var result1 =results.value[0]
sample code snippet for reference
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
for (var i = 0; i < results.value.length; i++) {
var abc = results.value[i]["abc"];
var xyz = results.value[i]["xyz"];
var pqr = results.value[i]["pqr"];
var pqr_formatted = results.value[i]["pqr#OData.Community.Display.V1.FormattedValue"];
}
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
Related
I have a function that calls an API (let's call it API-1) to get the song lyrics.
Since this API sometimes can't find a song in its database, I want to call another API (let's call it API-2) to do the same search.
I need to integrate the code of both APIs inside the function, when the first one doesn't get data.
I tell you some very important information:
In API-1 I must force the data to be fetched as XML and the responseType must be 'document'.
API-2 does not require any of the above conditions, the data is parced as JSON and the responseType it supports is 'text', but does not require it to be set, with 'document' it DOES NOT work, it gives error.
Now I will share the function code for API-1 and then I will share the same function code for API-2.
They both work perfect if I test them independently.
The help I am asking for is to integrate API-2 when API-1 does not fetch data.
Code using API-1
this.refreshLyric = function (currentSong, currentArtist) {
var xhr = new XMLHttpRequest;
xhr.open('GET', proxy_URL + api_URL + 'apiv1.asmx/SearchLyricDirect?artist=' + currentArtistE + '&song=' + ucwords(currentSongE), true);
// ONLY FOR THIS XMLHttpRequest responseType must be empty string or 'document'
xhr.responseType = 'document';
// ONLY FOR THIS XMLHttpRequest force the response to be parsed as XML
xhr.overrideMimeType('text/xml');
xhr.onload = function () {
if (xhr.readyState === xhr.DONE && xhr.status === 200) {
var openLyric = document.getElementsByClassName('lyrics')[0];
var lyric = xhr.responseXML.getElementsByTagName('Lyric')[0].innerHTML;
//check if any data was obtained
if (lyric != '') {
document.getElementById('lyric').innerHTML = lyric.replace(/\n/g, '<br />');
openLyric.style.opacity = "1";
openLyric.setAttribute('data-toggle', 'modal');
} else { /////// HERE INTEGRATE API-2 //////
openLyric.style.opacity = "0.3";
openLyric.removeAttribute('data-toggle');
var modalLyric = document.getElementById('modalLyrics');
modalLyric.style.display = "none";
modalLyric.setAttribute('aria-hidden', 'true');
(document.getElementsByClassName('modal-backdrop')[0]) ? document.getElementsByClassName('modal-backdrop')[0].remove(): '';
}
} else {
document.getElementsByClassName('lyrics')[0].style.opacity = "0.3";
document.getElementsByClassName('lyrics')[0].removeAttribute('data-toggle');
}
};
xhr.send();
}
The same code using API-2
this.refreshLyric = function (currentSong, currentArtist) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
var data = JSON.parse(this.responseText);
var openLyric = document.getElementsByClassName('lyrics')[0];
var lyric = data.mus[0].text;
//check if any data was obtained
if (lyric != '') {
document.getElementById('lyric').innerHTML = lyric.replace(/\n/g, '<br />');
openLyric.style.opacity = "1";
openLyric.setAttribute('data-toggle', 'modal');
} else {
openLyric.style.opacity = "0.3";
openLyric.removeAttribute('data-toggle');
var modalLyric = document.getElementById('modalLyrics');
modalLyric.style.display = "none";
modalLyric.setAttribute('aria-hidden', 'true');
(document.getElementsByClassName('modal-backdrop')[0]) ? document.getElementsByClassName('modal-backdrop')[0].remove(): '';
}
} else {
document.getElementsByClassName('lyrics')[0].style.opacity = "0.3";
document.getElementsByClassName('lyrics')[0].removeAttribute('data-toggle');
}
}
xhttp.open('GET', 'https://api.vagalume.com.br/search.php?apikey=' + API_KEY + '&art=' + currentArtist + '&mus=' + currentSong.toLowerCase(), true);
xhttp.send()
}
The shared codes are of the SAME function (this.refreshLyric), what has to be integrated is only the XMLHttpRequest API.
In the ELSE of line 23 of API-1 I must integrate the code of API-2.
I have already tried it in several ways but I am presented with syntax problems with the IF - ELSE conditionals and errors with the API-2 which is getting the responseType and the MimeType of API-1.
EDIT
FIXED: When API-1 cannot find the lyric, I have created a new function that calls API-2. refreshLyric2(currentSong, currentArtist); :)
this.refreshLyric = function (currentSong, currentArtist) {
var xhr = new XMLHttpRequest;
xhr.open('GET', proxy_URL + api_URL + 'apiv1.asmx/SearchLyricDirect?artist=' + currentArtistE + '&song=' + ucwords(currentSongE), true);
// ONLY FOR THIS XMLHttpRequest responseType must be empty string or 'document'
xhr.responseType = 'document';
// ONLY FOR THIS XMLHttpRequest force the response to be parsed as XML
xhr.overrideMimeType('text/xml');
xhr.onload = function () {
if (xhr.readyState === xhr.DONE && xhr.status === 200) {
var openLyric = document.getElementsByClassName('lyrics')[0];
var lyric = xhr.responseXML.getElementsByTagName('Lyric')[0].innerHTML;
//check if any data was obtained
if (lyric != '') {
document.getElementById('lyric').innerHTML = lyric.replace(/\n/g, '<br />');
openLyric.style.opacity = "1";
openLyric.setAttribute('data-toggle', 'modal');
} else {
//If lyric was not obtained, we call API-2
refreshLyric2(currentSong, currentArtist);
}
} else {
document.getElementsByClassName('lyrics')[0].style.opacity = "0.3";
document.getElementsByClassName('lyrics')[0].removeAttribute('data-toggle');
}
};
xhr.send();
}
refreshLyric2 = function (currentSong, currentArtist) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
var data = JSON.parse(this.responseText);
var openLyric = document.getElementsByClassName('lyrics')[0];
var lyric = data.mus[0].text;
//check if any data was obtained
if (lyric != '') {
document.getElementById('lyric').innerHTML = lyric.replace(/\n/g, '<br />');
openLyric.style.opacity = "1";
openLyric.setAttribute('data-toggle', 'modal');
} else {
openLyric.style.opacity = "0.3";
openLyric.removeAttribute('data-toggle');
var modalLyric = document.getElementById('modalLyrics');
modalLyric.style.display = "none";
modalLyric.setAttribute('aria-hidden', 'true');
(document.getElementsByClassName('modal-backdrop')[0]) ? document.getElementsByClassName('modal-backdrop')[0].remove(): '';
}
} else {
document.getElementsByClassName('lyrics')[0].style.opacity = "0.3";
document.getElementsByClassName('lyrics')[0].removeAttribute('data-toggle');
}
}
xhttp.open('GET', 'https://api.vagalume.com.br/search.php?apikey=' + API_KEY + '&art=' + currentArtist + '&mus=' + currentSong.toLowerCase(), true);
xhttp.send()
}
I am making a e-comers site.
https://colorlib.com/wp/template/onetech/ in this theme I am writting my own php code and changing some js.
But I face a problem and can't know how to solve this.
My html code was
<div class="product_fav"><i class="fas fa-heart"></i></div>
and js was `
function initFavs()
{
var fav = $('.product_fav');
fav.on('click', function()
{
fav.toggleClass('active');
});
}`
I change this html code to
<div class="product_fav"><i class="pro fas fa-check"></i></div> <span id="txtHint"></span>
and js to `
function initFavs()
{
var fav = $('.product_fav');
var faav = $('.pro');
faav.on('click', function()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
var xxhttp = new XMLHttpRequest();
xxhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("wili").innerHTML = this.responseText;
}
};
if(faav.hasClass('fa-times'))
{
faav.removeClass('fa-times');
faav.addClass('fa-check');
fav.toggleClass('active');
fav.removeClass('deactive');
xhttp.open("GET", "addfavorite.php?no=" + no + "&id=" + id + "", true);
xhttp.send();
xxhttp.open("GET", "totalfavorite.php?no=" + no + "", true);
xxhttp.send();
}
else if(faav.hasClass('fa-check') && fav.hasClass('active'))
{
faav.addClass('fa-times');
faav.removeClass('fa-check');
fav.toggleClass('deactive');
fav.removeClass('active');
xhttp.open("GET", "removefavorite.php?no=" + no + "&id=" + id + "", true);
xhttp.send();
xxhttp.open("GET", "totalfavorite.php?no=" + no + "", true);
xxhttp.send();
}
else if(faav.hasClass('fa-check'))
{
faav.removeClass('fa-times');
faav.addClass('fa-check');
fav.toggleClass('active');
fav.removeClass('deactive');
xhttp.open("GET", "addfavorite.php?no=" + no + "&id=" + id + "", true);
xhttp.send();
xxhttp.open("GET", "totalfavorite.php?no=" + no + "", true);
xxhttp.send();
}
});
}`
for this page http://shop.virusincbd.com/product.php
but I can't convert this code(html same) `
function initFavs()
{
// Handle Favorites
var items = document.getElementsByClassName('product_fav');
for(var x = 0; x < items.length; x++)
{
var item = items[x];
item.addEventListener('click', function(fn)
{
fn.target.classList.toggle('active');
});
}
}`
for this page http://shop.virusincbd.com/
You need to change from $('.pro').on('click' to $('.product_fav').on('click'
here is the working example:
https://codebrace.com/editor/b1c10075d
I need to set a contract lookup field in crm based on the account selected and business unit. This is a many to many relationship in crm .The best way i can think to do this is to create 2 querys/api calls (using crm rest builder) to be able to do this based on the criteria. the first query accesses the intersect table (account-contract table)in order to return all contracts based on the account and the seconds needs to further filter the results by looping through all the results from the first query and do a count off all the contracts that match the business unit selected. the issue im having now is that, i used an array to push all the values from the first query to be able to loop in the second one. However the array i created is not reaching the for loop thus the second query is not executing
function populateContractLookup() {
var buisnessUnitId = getFieldValue("hc_businessunit");
var worksiteId = getFieldValue("hc_worksite")[0].id;
worksiteId = stripCurlies(worksiteId);
if (buisnessUnitId != null) {
buisnessUnitId = stripCurlies(buisnessUnitId[0].id);
var condition = "_hc_businessunit_value eq " + buisnessUnitId + " and";
}
else {
condition = "";
}//to be able to count the how many contracts that would hav gotten populated to contract lookup field
var validcontractid;
var contractCount = 0;
var contractArray = [];
//this query gets all contracts based on account
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/hc_account_contractset?$select=contractid&$filter=accountid eq " + worksiteId, true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
// Xrm.Utility.alertDialog(results.value.length);
for (var i = 0; i < results.value.length; i++) {
var contractid = results.value[i]["contractid"];
// Xrm.Utility.alertDialog(contractid);
contractArray.push(contractid);
}
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}// Xrm.Utility.alertDialog(contractArray.length) prints to the screen here
};
req.send();
//query to furthr filter the above query to get all contracts based on the buisness unit
//Xrm.Utility.alertDialog(contractArray.length);//not printing to screen
for (var i = 0; i < contractArray.length; i++) {
Xrm.Utility.alertDialog("were in the loop"); //not reaching this loop
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contracts?$select=contractid&$filter=contractid eq " + contractArray[i] + " and _hc_businessunit_value eq " + buisnessUnitId, true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
Xrm.Utility.alertDialog(results.value.length);
for (var i = 0; i < results.value.length; i++) {
contractCount++;
}
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
}
}
.ANy ideas of why i cant access my arrary?
Your first request is asynchronous. The code after your first req.send() is executing immediately, whereas you need the result of your first request to have been returned before any other code executes.
You therefore need to wrap your second request, which is dependent on the result of the first, into a callback function. You then call this callback function in the success callback of your first request.
See this StackOverflow answer for information on callback functions.
As an aside, your second request won't work. You're trying to execute a request once per contract that was retrieved. What you want to do is build your OData filter by iterating over contractArray array and writing '(contractid eq ' + contractArray[i] + ') or' //...
As another aside, consider using a FetchXML aggregate to count records.
Your code might look something like this:
var buisnessUnitId = getFieldValue("hc_businessunit");
var worksiteId = getFieldValue("hc_worksite")[0].id;
function populateContractLookup() {
worksiteId = stripCurlies(worksiteId);
if (buisnessUnitId != null) {
buisnessUnitId = stripCurlies(buisnessUnitId[0].id);
var condition = "_hc_businessunit_value eq " + buisnessUnitId + " and";
}
else {
condition = "";
}//to be able to count the how many contracts that would hav gotten populated to contract lookup field
var validcontractid;
var contractCount = 0;
var contractArray = [];
//this query gets all contracts based on account
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/hc_account_contractset?$select=contractid&$filter=accountid eq " + worksiteId, true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
// Xrm.Utility.alertDialog(results.value.length);
for (var i = 0; i < results.value.length; i++) {
var contractid = results.value[i]["contractid"];
// Xrm.Utility.alertDialog(contractid);
contractArray.push(contractid);
}
// Call your callback function.
countContracts(contractArray);
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}// Xrm.Utility.alertDialog(contractArray.length) prints to the screen here
};
req.send();
}
Your callback function (though as I've mentioned above this needs rewriting):
function countContracts(contractArray) {
for (var i = 0; i < contractArray.length; i++) {
Xrm.Utility.alertDialog("were in the loop"); //not reaching this loop
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contracts?$select=contractid&$filter=contractid eq " + contractArray[i] + " and _hc_businessunit_value eq " + buisnessUnitId, true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
Xrm.Utility.alertDialog(results.value.length);
for (var i = 0; i < results.value.length; i++) {
contractCount++;
}
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
}
}
You can try switching the first call as synchronous by changing the flag like below & the result ll be available immediately before the second call.
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/hc_account_contractset?$select=contractid&$filter=accountid eq " + worksiteId, false);
The code below runs fine with a hard-coded tag name. I need to be able to call "loadDoc" with a variable that will return the tag I specify. I am rather new to JQuery and I'm not sure how to accomplish this.
Many thanks.
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
myFunction(xhttp);
}
}
xhttp.open("GET", "pyg280c.xml", true);
xhttp.send();
}
function myFunction(xml) {
var i;
var xmlDoc = xml.responseXML;
var htext = "";
var x = xmlDoc.getElementsByTagName("PYP280CR");
for (i = 0; i <x.length; i++) {
htext += "<p>" + x[i].getElementsByTagName("PCST")[0].childNodes[0].nodeValue + "</p>";
}
document.getElementById("helptext").innerHTML = htext;
}
Since you say it works fine when you hardcode the tag name then as #Hackerman said pass the tagname into the loadDoc function. Pass it on to the myFunction function and simply use the tag name variable in the getElementByTagName(tag) function (no quotes around variables). It should work.
function loadDoc(myTagName) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
myFunction(xhttp, myTagName);
}
}
xhttp.open("GET", "pyg280c.xml", true);
xhttp.send();
}
function myFunction(xml, tag) {
var i;
var xmlDoc = xml.responseXML;
var htext = "";
var x = xmlDoc.getElementsByTagName("PYP280CR");
for (i = 0; i <x.length; i++) {
htext += "<p>" + x[i].getElementsByTagName(tag)[0].childNodes[0].nodeValue + "</p>";
}
document.getElementById("helptext").innerHTML = htext;
}
FYI - You mentioned jQuery. There is no jQuery in your code. jQuery probably would have made this easier.
Jquery version including some default ajax error handling:
function loadDoc(tag){
$.ajax({
url: "pyg280c.xml",
type: "GET",
dataType: "xml",
success: function(xml){
var xmlDOC = $.parseXML(xml.responseXML);
var x = $(xmlDOC).find("PYP280CR");
var htexts = $.map(x, function(el, idx){
return $(el).find(tag).children()[0].val();
}
htext = htexts.join(" ");
$('#helptext').html(htext);
},
error: function (xhr, ajaxOptions, thrownError){
console.log('status = ' + xhr.status);
console.log('error = ' + thrownError);
}
}
Please help i have been trying from 1 hours and not able to get whats wrong
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/book/2279690981";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
myFunction(myArr);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(arr) {
var out = "";
var i;
for(i = 0; i < arr.length; i++) {
out = arr[i].ID + arr[i].Title + arr[i].Description;
}
document.getElementById("id01").innerHTML = out;
}
</script>
</body>
</html>
I am trying to fetch details from http://it-ebooks-api.info/v1/book/2279690981 but it show only empty array being returned. What changes are required ?
Modification
I added [ ] on JSON object and it worked .. Please can someone explain me.
Thank in advance :)
The response does not contain an array, so the for loop is not needed and this should get you the result you are looking for:
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/book/2279690981";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myresponse = JSON.parse(xmlhttp.responseText);
myFunction(myresponse);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(response) {
var out = "";
var i;
out = "<p>" + response.ID + response.Title + response.Description + "<p>";
document.getElementById("id01").innerHTML = out;
}
</script>
</body>
If you use the full listing available from http://it-ebooks-api.info/v1/search/php, then you need the for loop to go through the array like this:
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/search/php";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myresponse = JSON.parse(xmlhttp.responseText);
myFunction(myresponse.Books);
}
}
function myFunction(Books) {
var out = "";
for (var i = 0; i < Books.length; i++) {
out += "<p>ID: " + Books[i].ID + "</p>" + "<p>Title: " + Books[i].Title + "</p>" + "<p>Description: " + Books[i].Description + "</p>"
}
document.getElementById("id01").innerHTML = out;
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
</script>
</body>
</html>
And to make it slightly more elegant, you could have a function that adds the book and if you get only one book you can call it directly from the onreadystatechange, and if you have the full listing, then you can loop it through, but still use the same function. So something like this:
<!DOCTYPE html>
<html>
<body>
<div id="id01">Result<br/></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/search/php";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var response = JSON.parse(xmlhttpo.responseText);
if (response.Books) { // If the response object has Books array, we pass it to the parseBooks functoin to add them all one by one.
parseBooks(response.Books)
} else {
addBook(response); // If there is no Books array, we assume that there is only one book and add it to the list with addBook function.
}
}
}
function addBook (Book) {
var text = document.getElementById("id01").innerHTML;
var body = "<p>ID: " + Book.ID + "</p><p>Title: " + Book.Title + "</p><p>Description: " + Book.Description + "</p>";
document.getElementById("id01").innerHTML = text + body; // Append the innerHTML with the new Book.
}
function parseBooks(Books) {
for (var i = 0; i < Books.length; i++) {
addBook(Books[i]) // Add all books in the array one by one
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
</script>
</body>
</html>
You JSON feed is just a simple object and not an Array of objects. Note the opening curly braces in the returned feed: {}
You should then change your myFunction function so it goes through an object and not an array just by removing the for loop:
function myFunction(obj) {
var out = "",
id01 = document.getElementById("id01");
out = obj.ID + obj.Title + obj.Description;
id01.innerHTML = id01.innerHTML + out;
}
Edit:
You can use the same function then inside a for loop when you have to parse an Array of Objects.
Taking as a feed the JSON returned from http://it-ebooks-api.info/v1/search/php, you can retrieve the Books value and then loop through it:
var xmlhttp = new XMLHttpRequest();
var url = "http://it-ebooks-api.info/v1/book/2279690981";
var url2 = "http://it-ebooks-api.info/v1/search/php";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var rslt = JSON.parse(xmlhttp.responseText);
console.log(rslt);
var books = rslt.Books;
for (var i = 0; i < books.length; i++)
{
myFunction(books[i]);
}
}
}
xmlhttp.open("GET", url2, true);
xmlhttp.send();