Cannot read property 'length' of undefined jquery [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I am getting a list from C# web method with ajax (code below), the list is returned fine, but after the success method is done, it gives me an error - (Cannot read property 'length' of undefined) in the jquery (screenshot below)
Am I missing something ??
function getMainParentMenus() {
$.ajax({
type: "POST",
url: "/Mainpage.aspx/getLeftMainNavParentMenus",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d);
parentMenuss = msg.d;
}, //It goes to the screenshot below after this bracket
error: function (error) {
alert("An error has occured while fetching the Left Nav Parent Menus");
}
});
};
The method above is called by the below method.
var parentMenuss;
var listOfSubMenus;
function bindLeftNavMenu() {
// var parentMenus = getMainParentMenus();
getMainParentMenus();
var html = "<div id='accordian'> ddd";
$.each(parentMenuss, function () {
html += " <h3 class='accordianHeader' href='" + this['URL'] + "'>" + this['Title'] + "</h3> ";
alert("okK");
$.each(listOfSubMenus, function () {
html += "<div class='accordianContent'><a href='" + this['URL'] + "'>" + this['Title'] + "</a>";
});
});
html += "</div>";
$("#leftNavigationMenu").append(html);
};
EDIT :
the data in the alert in the first block of code above is displayed like so
and in the chrome debugger :

Because getMainParentMenus is using AJAX it is asynchronous. Your next line of code after calling getMainParentMenus will be executed before the .success part of your AJAX call, so it will be executed before parentMenuss has been populated.
There are a few ways you can tackle this, one way would be to pass the callback function to getMainParentMenus, something like this:
function getMainParentMenus(myCallback) {
$.ajax({
type: "POST",
url: "/Mainpage.aspx/getLeftMainNavParentMenus",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d);
parentMenuss = msg.d;
if (callback && typeof(callback)==="function") {
callback();
}
}, //It goes to the screenshot below after this bracket
error: function (error) {
alert("An error has occured while fetching the Left Nav Parent Menus");
}
});
};
Now you can call it like this:
var html = "<div id='accordian'> ddd";
getMainParentMenus(function() {
$.each(parentMenuss, function () {
html += " <h3 class='accordianHeader' href='" + this['URL'] + "'>" + this['Title'] + "</h3> ";
alert("okK");
$.each(listOfSubMenus, function () {
html += "<div class='accordianContent'><a href='" + this['URL'] + "'>" + this['Title'] + "</a>";
});
});
});

Your code for rendering the menus is being executed immediately after getMainParentMenus(); Javascript does not wait for the ajax call to complete before moving on to the next block. It is operating asynchronously, as others have mentioned in the comments.
Your code has to wait for the ajax call to complete before trying to display the data.
jQuery supports deferred execution and promises, so you can create code that will not execute until other code has completed. This is the preferred way of handling asynchronous operations.
Try this:
function getMainParentMenus() {
var request = $.ajax({
type: "POST",
url: "/Mainpage.aspx/getLeftMainNavParentMenus",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json"
}, //It goes to the screenshot below after this bracket
error: function (error) {
alert("An error has occured while fetching the Left Nav Parent Menus");
}
});
return request;
}
var parentMenuss;
var listOfSubMenus;
function bindLeftNavMenu() {
getMainParentMenus().success(function (result) {
var html = "<div id='accordian'> ddd";
$.each(parentMenuss, function () {
html += " <h3 class='accordianHeader' href='" + this['URL'] + "'>" + this['Title'] + "</h3> ";
alert("okK");
$.each(listOfSubMenus, function () {
html += "<div class='accordianContent'><a href='" + this['URL'] + "'>" + this['Title'] + "</a>";
});
});
html += "</div>";
$("#leftNavigationMenu").append(html);
});
}

Related

I want to set a url inside my ajax call back function

I want to make a clickable link in my ajax success response. But I could not do this.
<td id="attachment"></td>
function DoAction(id) {
$.ajax({
type: "get",
url: "/view_message",
data: "id=" + id,
dataType: 'json',
success: function(data) {
if (data) {
var text = "No Files There !";
$('#myModal').modal('show');
$('#subject').text(data.subject);
$('#body').text(data.body);
$('#created_at').text(data.created_at);
if (data.attachment) {
$('#attachment').html('<a href="files/' + data.attachment + '" />click</a>');
} else {
$('#attachment').text(text);
}
}
}
});
}
I want to display a clickable link in my .
I always encounter this when using ajax calls so;
Update your code from this.
$('#attachment').html('<a href="files/' + data.attachment + '" />click</a>');
To This.
$(document).find('#attachment').html('<a href="files/' + data.attachment + '" />click</a>');
if the code doesn't work add a console.log("working") function to see if your code is really reaching the success function.
I hope it helps.

JSON parsing and listing data in PhoneGap not working

I'm working on making an API call in PhoneGap. I wrote a function and calling it from a button click event, and I'm getting a response too, but I want to know how to display it. I have tried, but it's not working.
function getContactList() {
console.log("Entering getContactList()");
$.ajax({
url: "https://api.androidhive.info/contacts/",
dataType: "json",
cache: false,
error: function(xhr, ajaxOptions, thrownError) {
debugger;
alert(xhr.statusText);
alert(thrownError);
},
success: function(json) {
console.log("====CONTACTLIST ---->", json);
$(json).find("contacts").each(function() {
var html = '<li>' + $(this).find("name").text() +
' ' + $(this).find("name").text() + '</li>';
$('#contacts').append(html);
});
}
});
}
You're receiving JSON string which is then automatically converted by jQuery to a JavaScript object, so you can interact with it directly and shouldn't convert it to a jQuery object like $(json). Change the code inside your success to this:
for (var i = 0; i < json.contacts.length; i++) {
var c = json.contacts[i];
var html = '<li>' + c.name + ' ' + c.email + '</li>';
$('#contacts').append(html);
}
Note: it seems that there is an error in your code, you're using the find("name") twice. I changed it to name & email, but you can use any property of the contacts that you're getting.

using jQuery mobile with ajax

I am trying to print a jQuery mobile thing using ajax but it doesn't encode the result as jQuery mobile is supposed to do.
This is a simplified version of the part of the javascript code that is supposed to do so:
<script type="text/javascript">
function changePage(task) {
var objText = "";
$.ajax({
type: "POST",
url: "DataFetch.aspx/FetchData",
data: '{id: ' + <%=Session["loggedID"] %> + ', task: ' + task + ' }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var obj = JSON.parse(response.d);
if (task == 2)
{
objText += "<div data-role='collapsible'><h3>click me</h3><p>text</p></div>";
}
document.getElementById('content' + task).innerHTML = objText;
}
});
}
</script>
How can I make it work? (when I write it explicitly in the html or outside the ajax functions it works but I need it to work with json)
Try changing
document.getElementById('content' + task).innerHTML = objText;
to
$('#content' + task).HTML(objText).enhanceWithin();
The enhanceWithin() call tells jQM to enhace the new content you added via AJAX:
http://api.jquerymobile.com/enhanceWithin/

jQuery Loader on a Ajax request [duplicate]

This question already has answers here:
Add a loading animation to jquery ajax .load()
(5 answers)
Closed 8 years ago.
I am creating an application in Node, which pulls objects in my Schema (Mongo) and presents them in HTML. Okay, all right so far.
Now I need to create a jQuery loader, which features a picture like this while the objects do not appear in the html -> http://i.imgur.com/hq37Dew.gif while the data does not appear.
$.ajax({
type: 'GET',
url: host + '/datas',
success:function(datas) {
datas.forEach (function (data) {
var HTML = [];
HTML.push('<tr class="datas">');
HTML.push('<td>' + data.email + '</td>');
HTML.push('<td>' + name.email + '</td>');
reservasHTML.push('</tr>');
$('tbody').append(reservasHTML.join(''));
})
}
});
How I can do this?
$.ajax({
$(".datas").empty().html('<img src="http://i.imgur.com/hq37Dew.gif" />'); // SHOW THE AJAX LOADER
type: 'GET',
url: host + '/datas',
success:function(datas){
$(".datas").html(datas); // this will hide the loader and replace it with the data
datas.forEach (function (data) {
var HTML = [];
HTML.push('<tr class="datas">');
HTML.push('<td>' + data.email + '</td>');
HTML.push('<td>' + name.email + '</td>');
reservasHTML.push('</tr>');
$('tbody').append(reservasHTML.join(''));
})
}
});
I think this is it.
Assuming that you give the image an id of image_id ,
$.ajax({
type: 'GET',
url: host + '/datas',
beforeSend: function(){
// Code to show the image . e.g.
$('#image_id').show();
},
success:function(datas) {
// Code to hide image again / completely make it display-none
$('#image_id').hide // or $('#image_id').css("display","none");
reservas.forEach (function (data) {
// ........
})
}
});
$.ajax({
type: 'GET',
url: host + '/datas',
beforeSend: function() {
// Add loader here
$(placeholder).addClass('loading');
},
complete: function() {
//hide loader here/
$(placeholder).removeClass('loading');
},
success:function(datas){
datas.forEach (function (data) {
var HTML = [];
HTML.push('<tr class="datas">');
HTML.push('<td>' + data.email + '</td>');
HTML.push('<td>' + name.email + '</td>');
reservasHTML.push('</tr>');
$('tbody').append(reservasHTML.join(''));
})
}
});
hope this works

Returning Response in jquery ajax function

Getting problems in Response.d , based on the result which is returning by the checkusers() function I am saving the values. If the entered name is in already in database it should say "User already exists", if it is not in database it should create a new record.
But I am not getting the correct value from (response), I observed that Console.log(response.d) giving me correct values like 'true' or 'false'. I tried everything I know like-
changing async:"false"
var jqXHR = $.ajax({ and returning jqXHR.responseText
But none of they worked for me . Please help me with this.
submitHandler: function (form) {
var txtName = $("#txtName").val();
var txtEmail = $("#txtEmail").val();
var txtSurName = $("#txtSurName").val();
var txtMobile = $("#txtMobile").val();
var txtAddress = $("#txtAddress").val();
var obj = CheckUser();
if (obj == false) {
$.ajax({
type: "POST",
url: location.pathname + "/saveData",
data: "{Name:'" + txtName + "',SurName:'" + txtSurName + "',Email:'" + txtEmail + "',Mobile:'" + txtMobile + "',Address:'" + txtAddress + "'}",
contentType: "application/json; charset=utf-8",
datatype: "jsondata",
async: "true",
success: function (response) {
$(".errMsg ul").remove();
var myObject = eval('(' + response.d + ')');
if (myObject > 0) {
bindData();
$(".errMsg").append("<ul><li>Data saved successfully</li></ul>");
}
else {
$(".errMsg").append("<ul><li>Opppps something went wrong.</li></ul>");
}
$(".errMsg").show("slow");
clear();
},
error: function (response) {
alert(response.status + ' ' + response.statusText);
}
});
}
else {
$(".errMsg").append("<ul><li>User Already Exists </li></ul>");
$(".errMsg").show("slow");
}
}
});
$("#btnSave").click(function () {
$("#form1").submit()
});
});
checkusers function is:
function CheckUser() {
var EmpName = $("#txtName").val();
$.ajax({
type: "POST",
url: location.pathname + "/UserExist",
data: "{Name:'" + EmpName + "'}",
contentType: "application/json; charset=utf-8",
datatype: "jsondata",
async: "true",
success: function (response) {
console.log(response.d);
},
error: function (response) {
alert(response.status + ' ' + response.statusText);
}
});
}
Just because your database returns true or false doesn't mean this also gets returned by your CheckUser().
There are several options here:
Either you make a local variable in your CheckUser, Make your Ajax call synchronous, set the local variable to response.d in the success function and then return that local variable.
Another option is to work with Deferred objects and make your submithandler Ajax call wait for the Checkuser Ajax call to return;
A third option is to call your create ajax call from your success callback in your CheckUser Ajax call if the user isn't created yet.
I would recommend either option 2 or 3, because option 1 is not userfriendly.

Categories

Resources