Cannot read property of undefined after JSON parse - javascript

I have done an ajax request in my code and it works good. After that I want to extract only the necessary info and re-post it to another script. Until now here is my code:
$.ajax({
type: "POST",
url: url,
data: {xhr_id: xhr_id},
success: function (jsondata) {
var product_data = [];
for (var i = 0; i <= 3; i++) {
//alert(jsondata.products[i].product_description.toSource());
product_data[i] = {};
product_data[i]["product" + i] = jsondata.products[i].product_description;
//alert(product_data[i]["product" + i].toSource());
}
},
dataType: "json"
});
The problem is that both the alerts work fine, displaying the information I want. However, I get an error message of "Uncaught TypeError: Cannot read property 'product_description' of undefined" which breaks the script and prevents me from doing anything else. What am I doing wrong, any ideas?

'product_description' of undefined" what it means is that your are trying to access property on undefined variable. That implies "jsondata.products[i]" resulted in undefined value which have occured due to index out of range.How many records are returned in jsondata 3 or 4,check and adjust the condition in for loop

The parameter in the success() function of $.ajax is a string. You have to put it through a parse function to make json. See your code below modified but not tested.
$.ajax({
type: "POST",
url: url,
data: {xhr_id: xhr_id},
success: function (jsondata) {
var oData;
try { oData=jQuery.parseJSON(jsondata) }
catch(err) {
alert("Problem parsing json string : " + jsondata)
return false
}
var product_data = [];
for (var i = 0; i <= 3; i++) {
//alert(oData.products[i].product_description.toSource());
product_data[i] = {};
product_data[i]["product" + i] = oData.products[i].product_description;
//alert(product_data[i]["product" + i].toSource());
}
},
dataType: "json"
});

Related

Localstorage setting through ajax data randomly gets undefined

I am setting items to localstorage using the below code. The issue I am getting is whenever I refresh the page some of the items are not set when I inspect the localstorage it shows as undefined, this is absolutely random and sometimes all items are set parfectly. How can I ensure that all the items are set without any undefined?
const catdata = [];
var catArr = JSON.parse(localStorage.getItem('cat'));
for (let i = 0; i < catArr.length; i++) {
const catid = catArr[i]['id'];
const catname = catArr[i]['name'];
$('#topitems').prepend('<div ><a class="topitems" href="'+catArr[i]['id']+'">'+catArr[i]['name']+'</a></div>');
(function(i) {
$.ajax( { url : "sales/item_search_cat?cat="+catid
, data : "GET"
// , async: "false",
, dataType : "json"
, success : function(data) {
catdata.push(data);
localStorage.setItem(catid,JSON.stringify(catdata[i]));
}
});
})(i);
}
The execution of the ajax requests are not sequentially executed, and sometimes your code is accessing an index that doesn't exist.
For example, one response arrives with index 2, the code pushes into the empty array at index 0, and catdata[i] is trying to get the index 2.
I think you have to call the ajax request using await or you can use the data directly:
localStorage.setItem(catid, JSON.stringify(data));
Possible solution (I didn't test it):
The execution is async, if you need to wait for the executions, you have to follow an async/await approach.
function callAjax(catid) {
$.ajax({
url: "sales/item_search_cat?cat=" + catid,
data: "GET",
dataType: "json",
success: function(data) {
localStorage.setItem(catid, JSON.stringify(data));
success(data);
}
});
}
let catArr = JSON.parse(localStorage.getItem('cat'));
catArr.forEach(function({id: catid, name: catname}) {
$('#topitems').prepend('<div ><a class="topitems" href="' + catid + '">' + catname + '</a></div>');
callAjax(catid);
});

How can I resolve XML Parsing Error: not well-formedLocation?

On load of my page I execute this function
function getConnection() {
$.ajax({
type: "GET",
url: "../webservice/anonymous_PS.asmx/Get",
data: { "PSname": "LISTE_CONNEXTION" },
async : false ,
success: function (response) {
var data = response.getElementsByTagName("NewDataSet")[0]
for (let i = 0; i < data.children.length; i++) {
var c1Nb = $(data.children[i]).find('c1').text()
var c2Nb = $(data.children[i]).find('c2').text()
var c1 = document.getElementById("cs" + c1Nb)
var c2 = document.getElementById("cs" + c2Nb)
var line = $("#l_" + c1Nb + "_" + c2Nb)
}
}
})
}
But when I do that I have this error on Firefox :
XML Parsing Error: not well-formed
Location:
Line Number 1, Column 131:
and on chrome sometimes I have this error :
devtools was disconnected from the page
How can I resolve my issue ?
Try parsing your response, you can use $.parseXML(response) if you want to parse your response to xml or $.parseHTML(response) if you want to parse your response to html.
Once the parsing is done then your getElementsByTagName("NewDataSet")[0] will work and you will not get any error.
The final code will look something like:
var parsedResponse = $.parseXML(response);
var data = parsedResponse.getElementsByTagName("NewDataSet")[0];

Cannot read property 'length' of undefined AJAX

I have searched throughout SO about this issue, but I'm not getting any results in my code.
I have a simple JSON parser here, which creates a table based on a JSON object returned by an endpoint. Here is what I have tried so far.
function getAJAXData(APIurl){
$.ajax({
url: APIurl,
type: "GET",
dataType: "json"
}).then(function(data){
alert(data);
});
}
function generateTable(tableId){
var objRecords = getAJAXData("http://jsonplaceholder.typicode.com/posts");
var cols = addTableHeaders(objRecords, tableId);
for(var i = 0; i < objRecords.length; i++){
var tRow = $('<tr/>');
for (var colIdx = 0; colIdx < cols.length ; colIdx++){
var cellVal = objRecords[i][cols[colIdx]];
cellVal = (cellVal == null) ? "" : cellVal;
tRow.append($('<td/>').html(cellVal));
}
$(tableId).append(tRow);
}
}
function addTableHeaders(myList, tableId){
var colSet = [];
var headers = $('<tr/>');
for (var i = 0; i < myList.length; i++) {
var hRow = myList[i];
for(var key in hRow){
if($.inArray(key, colSet) == -1){
colSet.push(key);
headers.append( $('<th/>').html(key) );
}
}
}
$(tableId).append(headers);
return colSet;
}
That one doesn't work but when I hard-code a list, it generates a table from the hard-coded list. Can someone please explain what I am doing wrong or missing in the code? Thanks .
These two lines are an issue:
var objRecords = getAJAXData("http://jsonplaceholder.typicode.com/posts");
var cols = addTableHeaders(objRecords, tableId);
First off, your getAJAXData function doesn't return anything, so objRecords will always be undefined.
Second, even if it did return something, it's an asyncronous call, so the data won't be ready right away.
What you need to do is to wrap up the relevant bits of your code into a function and call it on the success callback so it gets executed only after your AJAX data is ready.
You need to call addTableHeaders inside of ajax success
$.ajax({
url: APIurl,
type: "GET",
dataType: "json",
success: function(data){
//call it here
}
})
});

Ajax data collection - Empty Set?

I'm doing an ajax call to a php query that I know returns results. However, I'm getting an empty set ("[]"). Here's my code:
var source = [];
// Get the user data to build the sources
function getUsers() {
var data = $.ajax( {
url: '/s/calendar_userdata.php',
method: 'GET',
dataType: 'json',
success: function(userData) {
console.log(userData); // returns []
var len = userData.length;
for(var i = 0; i < len; i++)
{
source[i] = '/s/events.php?e=' + userData[i]; // error "Uncaught TypeError: Cannot set property '0' of undefined"
}
return source;
}
});
}
I've done a lot of reading of StackOverflow and several tutorials on ajax calls and callbacks specifically. However, I'm stuck. Can someone show me what I've got wrong? I've been on this topic for the past 10 hours and am no longer making progress. Thanks.
Are you sure that's returning a body?
Maybe you could first do a
curl -i {host}:/s/calendar_userdata.php
and post it as an edit.
Also, you could also get the status in the ajax call so you can assure you are not throwing useful information such as a 404 (NOT FOUND).
function getUsers() {
var data = $.ajax( {
url: '/s/calendar_userdata.php',
method: 'GET',
success: function(userData, status) {
console.log('userData: ' + userData + ', status:' + status); // returns []
var len = userData.length;
for(var i = 0; i < len; i++)
{
source[i] = '/s/events.php?e=' + userData[i]; // error "Uncaught TypeError: Cannot set property '0' of undefined"
}
return source;
}
});

jQuery Ajax call in loop losing local variable reference

I am making several jQuery ajax calls within a loop. Each time one of the ajax calls return I need to reference a value corresponding to the original ajax call. My current code doesn't work properly, in that the value of the lskey variable has been altered by further loop iterations.
Here is the code:
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
success: function (data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(lskey); // Remove the relevant localStorage entry
}
, error: function (data) { $('#rollinginfo').append('<br />ERR:' + data); }
});
}
}
The problem is that lskey is being altered each time the loop executes, and therefore the success callback does not have a reference to the value of lskey that existed at the time of the call.
How do I reference the correct value of lskey for each success callback?
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
local_lskey: lskey
success: function (data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(this.local_lskey); // Remove the relevant localStorage entry
}
, error: function (data) { $('#rollinginfo').append('<br />ERR:' + data); }
});
}
}
This should work.
In the end I added the key info to the server posting, and then returned it from the server in JSON format so the success function could then simply refer to the key contained in the server response.
Have you considered chaining the AJAX calls? Basically you can make one AJAX call, process the result, modify lskey, etc. Then when you are ready, increment i and issue the second AJAX call. Loop this way instead of using the for loop...
You could put your ajax call into its own function and pass the lskey and postData values in. That way localStorage.removeItem(lskey) will refer to the lskey variable in the context of the function rather than the context of the loop.
Example
Declare the function -
function postForm(postdata, lskey) {
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
success: function(data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(lskey); // Remove the relevant localStorage entry
},
error: function(data) {
$('#rollinginfo').append('<br />ERR:' + data);
}
});
}
Then you can call your function from your loop -
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
postForm(postdata, lskey);
}
}
You could also declare the function just before the loop (assigning it to a variable) and then call it within the loop.
var postForm = function(postdata, lskey) {
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
success: function(data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(lskey); // Remove the relevant localStorage entry
},
error: function(data) {
$('#rollinginfo').append('<br />ERR:' + data);
}
});
}
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
postForm(postdata, lskey);
}
}

Categories

Resources