jQuery nested each/Ajax issue - javascript

I have nested each loops but an Ajax request in the second loop seems to not be adding to a variable that I declare in the first loop.
This is an example ("personal" information excluded) of what I am using:
var pages = [["Page Title 1", ["Page URL 1", "Page URL 2", "Page URL 3"]], ["Page Title 2", ["Page URL 1", "Page URL 2", "Page URL 3"]], ["Page Title 3", ["Page URL 1", "Page URL 2", "Page URL 3"]]];
function loadFeeds() {
$.each(pages, function(index, page) {
$(".pages").append("<a class=\"pagename\" href=\"#" + page[0] + "\">" + page[0] + "</a>");
html = "<div class=\"page\" id=\"" + page[0] + "\">";
$.each(page[1], function(index, feedUrl) {
$.ajax({
type: "GET",
url: feedUrl,
processData : true,
data: {
tagmode: "any"
},
jsonp: "jsonp",
dataType: "jsonp",
success: function(data) {
html += "Some header HTML";
$.each(data.responseData.feed.entries, function(i,entry) {
if (entry.image_urls.length === 0) {
html += "HTML from the data";
}
else {
html += "More HTML";
}
if ( i == 34 ) return false;
});
html += "Closing tags from the header";
afterAjax();
// console.log(html); returns correct information here
},
error: function(x,y,z) {
alert(x.responseText);
}
});
// console.log(html); returns everything declared to html OUTSIDE of the ajax request
});
$("body").append(html + "</div>");
// Also tried: $("body").ajaxStop(function(){ $(this).append(html + "</div>"); }); because Ajax is asynchronous
});
}​
Any ideas as to what is going on?
EDIT:
Full non-working demo, WIP page functionality: http://jsfiddle.net/SO_AMK/u42uy/
Full working demo, no page functionality:
Full screen: http://jsfiddle.net/SO_AMK/LXkaN/embedded/result/
Normal: http://jsfiddle.net/SO_AMK/LXkaN/
Please note that these are without images and are not the full app.

The Issue
Looks like a race condition. Remember that AJAX runs asynchronously and thusly, the success handler will run at some point in the future after the AJAX response has been received successfully. While the AJAX request is dispatched the rest of the script is executing. Specifically speaking:
$("body").append(html + "</div>");
Is running before the success handler is fired; meaning your html variable has not been updated at all yet.
Solution 1
Move
$("body").append(html + "</div>");
Within your success handler.
html += "Closing tags from the header";
afterAjax();
// console.log(html); returns correct information here
$("body").append(html + "</div>");
},
Solution 2 ($.ajaxStop)
Ensure that you register your handler before your make your $.ajax() calls. This will ensure your AJAX requests don't fire and finish before your code that registers your handler for .ajaxStop.
function loadFeeds() {
html = "";
$.ajaxStop(function(){$(document.body).append(html + "</div>);
$.each(pages, function(index, page) {
$(".pages").append("<a class=\"pagename\" href=\"#" + page[0] + "\">" + page[0] + "</a>");
html = "<div class=\"page\" id=\"" + page[0] + "\">";
...
}
Solution 3 (From your jsLint+Deffereds)
This example is taken from your fully working jsLint link. This code takes all of the $.ajax requests being created in your loop and stores in them in an arrary to be latter applied to a $.when().done() call. $.when() will inspect each $.ajax request applied to it and when it is done, call the handler specified in $.done(). Each $.ajax request stores its response in the html = [] array that is defined at the start of $.ready(). When the defered check ($.when()) sees all the $.ajax requests have completed we then join the array (array.join('')) to make 1 big HTML block and append it to the document. We then call your afterAjax() function.
$(document).ready(function () {
var html = [];
var feeds = ["http://pulsesubscriber.appspot.com/items?feed=http://feeds.gawker.com/lifehacker/vip&jsonp=?",
"http://pulsesubscriber.appspot.com/items?feed=http://allthingsd.com/feed&jsonp=?",
"http://pulsesubscriber.appspot.com/items?feed=http://feeds.cnet.com/latestnews/pulse&jsonp=?"];
loadFeeds(feeds);
function loadFeeds(feeds) {
var requests = [];
$.each(feeds, function(index, feedUrl) {
requests.push($.ajax({
type: "GET",
url: feedUrl,
processData : true,
data: {
tagmode: "any"
},
jsonp: "jsonp",
dataType: "jsonp",
success: function(data) {
var feedElements = "<header class=\"feed-title\"><div class=\"feed-title-content\"><span class=\"feed-title-text\">" +
data.responseData.feed.title +
"</span></div></header><section class=\"row\"><div class=\"scroll-left\"></div><div class=\"row-scroll\">";
$.each(data.responseData.feed.entries, function(index,entry) {
var feedElements = '';
if (entry.image_urls.length === 0) {
feedElements += "<div class=\"tile no-img\"><title class=\"tile-title no-img\">" +
entry.title +
"</title><hr class=\"no-img hr\" /><span class=\"no-img excerpt\">" +
entry.contentSnippet +
"</span><div class=\"tile-modal\"><div class=\"article-wrapper\">\r\n<div class=\"article-header\">\r\n<a class=\"article-title-link\" target=\"_blank\" href=\"" +
entry.link +
"\">\r\n<h1 class=\"article-title\">" +
entry.title +
"</h1>\r\n</a>\r\n<h2 class=\"article-byline\">By " +
entry.author +
": " +
data.responseData.feed.title +
"</h2>\r\n</div>\r\n<hr class=\"article-hr\"/>\r\n<div class=\"article-content\">" +
entry.content +
"\r\n<a class=\"read-more\" target=\"_blank\" href=\"" +
entry.link +
"\">Read More...</a>\r\n</div>\r\n</div></div></div>\r\n";
}
else {
feedElements += "<div class=\"tile\"><img class=\"tile-image\" src=\"" +
entry.image_urls[0] +
"\" /><title class=\"tile-title\">" +
entry.title +
"</title><div class=\"tile-modal\"><div class=\"article-wrapper\">\r\n<div class=\"article-header\">\r\n<a class=\"article-title-link\" target=\"_blank\" href=\"" +
entry.link +
"\">\r\n<h1 class=\"article-title\">" +
entry.title +
"</h1>\r\n</a>\r\n<h2 class=\"article-byline\">By " +
entry.author +
": " +
data.responseData.feed.title +
"</h2>\r\n</div>\r\n<hr class=\"article-hr\"/>\r\n<div class=\"article-content\">" +
entry.content +
"\r\n<a class=\"read-more\" target=\"_blank\" href=\"" +
entry.link +
"\">Read More...</a>\r\n</div>\r\n</div></div></div>\r\n";
}
html.push(feedElements);
console.log('updated elements');
if(index == 34 ){
return false;
}
});
},
error: function(x,y,z) {
console.log(x.responseText);
}
}));
});
$.when.apply(this,requests).done(function(){
console.log('when!');
console.log(html);
$(document.body).append($(html.join('')));
afterAjax();
});
}
$("#refresh-all").click(function(){
$("body > header, body > section").remove();
$("body").removeClass("active");
loadFeeds();
});
function afterAjax() {
$(".page:first").addClass("active");
$(".tile").click(function(){
if ($(".tile-modal.tile-modal-active").length) {
$(".tile-modal.tile-modal-active").removeClass("tile-modal-active");
$(this).children(".tile-modal").addClass("tile-modal-active");
}
else {
$(this).children(".tile-modal").addClass("tile-modal-active");
$("body").addClass("active");
}
});
$(".scroll-left").hover(function(){
$(this).parent().animate({scrollLeft: 0}, 7000);
}, function() {
$(this).parent().stop();
});
$(".scroll-right").hover(function(){
$(this).parent().animate({scrollLeft: $(this).siblings(".row-scroll").width()}, 7000);
}, function() {
$(this).parent().stop();
});
}
});
If you would like to execute a series of requests and once they have all executed do another action, you can utilize Futures & Promises Pattern or deffereds. In jQuery this is done in via .promise()(Futures/Promises) or .when() (Deffered).
A Note on Global Variables
It is also worth noting that not use var html = ... makes your variable a global; which is generally frowned upon. It would be best once moving $("body").append(html+"</div>") within the success handler to also declare html as var html.

ajaxStop is not firing because jsonp requests are by default not global. See here
I've updated your fiddle that forces jsonp requests as global. http://jsfiddle.net/u42uy/3/
*edit typo

Unless your ajax calls are synchronous (and I see no signs that they are), your each loop will finish and return BEFORE the ajax calls success functions run. You CANNOT structure your code this way. That means that $("body").append(html + "</div>"); will run before the ajax calls get a chance to add anything to your html variable.
You need to think about ajax response callbacks as independent pieces of code that run on their own timing sometime after your .each() loops are done and design the handling of the responses with that assumption in mind. Also keep in mind that multiple ajax calls aren't even guaranteed to complete in the order they were sent.
You could order the ajax calls by sending one and not sending the next until that one completes, keeping the combined html in a string variable like you have and then in the completion function of the last ajax call, you append the final accumulated html string to the body.
Here's another problem. At the start of your first .each() loop, you have this;
html = "<div class=\"page\" id=\"" + page[0] + "\">";
That reinitailizes the html variable, overwriting any results that might already be in there. You need to initialize it once before any .each() loop.

Do the follow:
Add var html = '' after var pages (line 1);
Change html = to html += (line 6);
Add html = '' after $("body").append(html + "</div>"); (line 41).
Result:
var pages = [["Page Title 1", ["Page URL 1", "Page URL 2", "Page URL 3"]], ["Page Title 2", ["Page URL 1", "Page URL 2", "Page URL 3"]], ["Page Title 3", ["Page URL 1", "Page URL 2", "Page URL 3"]]];
var html = ''; // ADD THIS
function loadFeeds() {
$.each(pages, function(index, page) {
$(".pages").append("<a class=\"pagename\" href=\"#" + page[0] + "\">" + page[0] + "</a>");
html += "<div class=\"page\" id=\"" + page[0] + "\">"; //ADD THE +
$.each(page[1], function(index, feedUrl) {
$.ajax({
type: "GET",
url: feedUrl,
processData : true,
data: {
tagmode: "any"
},
jsonp: "jsonp",
dataType: "jsonp",
success: function(data) {
html += "Some header HTML";
$.each(data.responseData.feed.entries, function(i,entry) {
if (entry.image_urls.length === 0) {
html += "HTML from the data";
}
else {
html += "More HTML";
}
if ( i == 34 ) return false;
});
html += "Closing tags from the header";
afterAjax();
},
error: function(x,y,z) {
alert(x.responseText);
}
});
});
$("body").append(html + "</div>");
html = ''; // RESET HTML TO NEXT Each
});

Related

Fix Ajax call not binding the result to a HTML id

I am writing some jQuery and Java code that sends an ajax call to my Java backend to do a procedure and then sends the results back to my jQuery. However, when I run a debug I notice that the information is being sent from Java to jQuery successfully, the issue is the jQuery is cutting off the remaing words after the first space. Below is my code and the result.
Jquery:
function fillInGPData() {
$.ajax({
type : "POST",
contentType : 'application/json; charset=utf-8',
dataType : 'json',
url : "/ajax/getGPdata",
data : JSON.stringify(""),
success : function(result) {
console.log("Result Selector: " + result);
console.log(result == null);
$.each(result, function(i, obj) {
console.log("Object: " + obj);
console.log("Tier: " + obj.tier);
console.log( "Selname: " + obj.selname);
console.log("Query: " + obj.query);
console.log("Description: " + obj.description);
console.log("Comment: " + obj.comments);
$(".tableBody1").append(
"<tr id=" + obj.selname + ">"
+ "<td class='sm-width-td'>"
+ obj.selname + "</td>" + "</tr>");
});
},
error : function(err) {
console.log(err);
}
});
}
Result:
<tr id="Windows" file="" share=""><td class="sm-width-td">Windows File Share</td></tr>
So its the obj.selname that is giving the issue. For example, if I pass Windows File Server, it will only show Windows for the ID. That where the problem is. I just need help figuring out why that is the case.

Communication beetween Javascript and PHP scripts in web app

THE CONTEXT
I'm developing a web app that loads contents dynamycally, retrieving data from a
catalogue of items stored as a MongoDB database in which records of the items and their authors are in two distinct collections of the same database.
Authors ID are stored in the item field creator and refer to the author field #id. Each item can have none,one or many authors.
Item sample
{
"_id" : ObjectId("59f5de430fa594333bb338a6"),
"#id" : "http://minerva.atcult.it/rdf/000000016009",
"creator" : "http://minerva.atcult.it/rdf/47734211-2637-3895-a690-4f33412931ec",
"identifier" : "000000016009",
"issued" : "fine sec. XIV - inizi sec. XV",
"title" : "Quadrans vetus",
"label" : "Quadrans vetus"
}
Author sample
{
"_id" : ObjectId("59f5d8e80fa594333bb1d72c"),
"#id" : "http://minerva.atcult.it/rdf/0007e43e-107f-3d18-b4bc-89f8d430fe59",
"#type" : "foaf:Person",
"name" : "Risse, Wilhelm"
}
WHAT WORKS
I query the database submitting a string in a form, using this PHP script
ITEM PHP SCRIPT
<?php
require 'vendor/autoload.php';
$title=$_GET['item'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->items;
$regex=new MongoDB\BSON\Regex ('^'.$title,'im');
$documentlist=$collection->find(['title'=>$regex],['projection'=>['_id'=>0,'title'=>1,'creator'=>1,'issued'=>1]]);
$items=$documentlist->toArray();
echo (json_encode($items));
?>
called by a Javascript script (new_search.js) using ajax, that has also the responsibility to attach to html document a <li class=item> for every item that matches the query, inserting the JSON fields and putting them in the provided tags ( <li class=item-name>,<li class=auth-name, and the last <li> in div class=item-info for date).
WHAT DOES NOT WORK
My intent is reproduce the pattern to retrieve author names from another collection in the same database, querying it using author field #id from the html tag <li class=auth-name, using a similar php script and a similar ajax call.
I tried to make a nested ajax call (in the one I used to retrieve the items infos) to invoke author_query.php that performs the MongoDB query on the collection of authors.
So, the question is: Is it possible use the $_GET superglobal to get the html tag that contains the author id #id in order to search it in the database?
Otherwise, how can I adjust the code to pass a javascript variable to php (not by user input) that lets me keep the content already loaded on the page?
UPDATES
To make clearer the question, I follow the tips in the comments and I updated my scripts using JSON directly to provide the needed data.
I also perfom a debug on the js code and it's clear that PHP don't provide any response,in fact ajax calls for authors name fails systematically.
I suppose that occurs because PHP don't receive the data dueto the fact I'm not using the correct syntax probably (in js code or in the php with $_GET or in both) to pass the variable author (I also tried data:'author='+author treating the JSON object author has a string). Anyway I don't understand what is the correct form to write the variable to pass using the data field of ajax().
MY SCRIPTS
JS SCRIPT new_search.js
$(document).ready(function () {
$("#submit").on("tap", function () {
var item = document.getElementById("search").value;
var author;
$.ajax({
url: "item_query.php",
type: "GET",
data: 'item=' + item,
dataType: "json",
async:false,
success: function (items) {
for (var i = 0; i < items.length; i++) {
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + items[i].creator+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
$('.item').each(function () {
author = $(this).find('.auth-name').text();
if (author == 'undefined')
$(this).find('.auth-name').text('Unknown');
else if(author.indexOf(',')!=-1) {
author='[{"author":"'+author+'"}]';
author=author.replace(/,/g,'"},{"author":"');
author = JSON.parse(author);
console.log(author);
$.ajax({
url: "author_query.php",
type: "GET",
data: author,
dataType: "json",
processData: false,
success: function (auth_json) {
$(this).find('.auth-name').text('');
var author_text=' ';
for(var i=0;i<auth_json.length;i++)
author_text+=auth_json.name+' ';
$(this).find('.auth-name').text(author_text);
},
error: function () {
console.log('Error 1');
}
});
}
else{
author='{"author":"'+author+"}";
author=JSON.parse(author);
$.ajax({
url: "author_query.php",
type: "GET",
data: author,
dataType: "json",
processData: false,
success: function (auth_json) {
$(this).find('.auth-name').text(auth_json.name);
},
error: function () {
console.log('Error 2');
}
});
}
});
});
});
AUTHOR PHP SCRIPT author_query.php
<?php
require 'vendor/autoload.php';
$auth=$_GET['author'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->persons;
if(is_array($auth)){
foreach ($auth as $a){
$document=$collection->findOne(['#id'=>$a],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json[]=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
}
else{
$document=$collection->findOne(['#id'=>$auth],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
echo (json_encode($auth_json));
?>
"I'm sure that authors array... is not empty and actually contains the authors IDs". You mean the jQuery object $('.item')? I think that it is empty, because it is created too soon.
The first $.ajax call sends an ajax request and sets a handler to add more stuff to the HTML, including elements that will match the CSS selector .item. But the handler doesn't run yet because it's asynchronous. Immediately after this, the object $('.item') is created, but it's empty because the new .item elements haven't been created yet. So no more ajax requests are sent. Some time later, the call to item_query.php returns, and the new HTML stuff is added, including the .item elements. But by now it's too late.
You say the array was not empty. I suspect you checked this by running the CSS selector after doing the search, after the return of the ajax call.
A lot of newbies have problems like this with asynchronous javascript. If you want to use the result of an asynchronous function in another function, you have to call the second function inside the callback function of the first one. (Actually there are more sophisticated ways of combining asynchronous functions together, but this is good enough for now.)
On a side note, you've done this in a slightly strange way where you save data in HTML, and then read the HTML to do some more stuff. I wouldn't use HTML as a storage place - just use variables like you would for most other things.
Try this:
$.ajax({
url: "item_query.php",
...
success: function (items) {
for (var i = 0; i < items.length; i++) {
var author = items[i].creator;
var authors;
// insert code here to generate authors from author.split(',') .
// authors should look something like this: [{author: 'http://minerva.atcult.it/rdf/47734211-2637-3895-a690-4f33412931ec'}] .
$.ajax({
url: "author_query.php",
type: "GET",
data: JSON.stringify(authors),
...
success: function (auth_json) {
...
},
error: function () {
console.log('Error 1');
}
});
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + items[i].creator+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
I make the first call to retrieve the item infos asynchronous and the nested that search for the authors name synchronous. In this way I solved the problem.
For sure it is not the best solution, and it needs a quite long,but acceptable, time (<1 second) to load the content.
JS SCRIPT
$(document).ready(function () {
$("#submit").on("tap", function () {
var item = document.getElementById("search").value;
$.ajax({
url: "item_query.php",
type: "GET",
data: 'item=' + item,
dataType: "json",
success: function (items) {
for (var i = 0; i < items.length; i++) {
var authors_names=' ';
var authors= JSON.stringify(items[i]);
if(authors.indexOf('creator')!=-1){
if(authors.charAt(authors.indexOf('"creator":')+'"creator":'.length)!='[')
authors=authors.substring(authors.indexOf('"creator":"'),authors.indexOf('"',authors.indexOf('"creator":"')+'"creator":"'.length)+1);
else
authors=authors.substring(authors.indexOf('"creator"'),authors.indexOf(']',authors.indexOf('"creator"'))+1);
authors='{'+authors+'}';
//console.log(authors);
$.ajax({
url: "author_query_v3.php",
type: "GET",
data: 'authors='+authors,
dataType:"json",
async:false,
success: function (auth_json) {
authors=[];
authors=auth_json;
var author;
for(var j=0;j<authors.length;j++){
author=JSON.parse(authors[j]);
authors_names+=author.name+" | ";
}
console.log(authors_names);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR+' '+textStatus+ ' '+errorThrown);
}
});
}
else{
authors_names='Unknown';
}
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + authors_names+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
});
});
PHP SCRIPT
<?php
require 'vendor/autoload.php';
$auth=$_GET['authors'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->persons;
$auth=json_decode($auth);
$auth=$auth->creator;
if(is_array($auth)) {
foreach ($auth as $a) {
$document = $collection->findOne(['#id' => $a], ['projection' => ['_id' => 0, 'name' => 1]]);
$auth_json[] = (MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
}
else{
$document=$collection->findOne(['#id'=>$auth],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json[]=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
echo(json_encode($auth_json));
?>

I keep getting this error SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data

This one is making me sick.because i cant find where i am going wrong.I will
appreciate any help or hint from you. below is my javascript code.so far the server side is fine but display the actual comment on the client side is the problem. please help me.
$(document).ready(function () {
// process the form
$('form.comments_form').each(function () {
var form_to_submit = $(this);
form_to_submit.submit(function (event) {
event.preventDefault();
var posta_id = form_to_submit.find("input[type=hidden].UNIQUE_ID").val();
var tetxarea1 = form_to_submit.find("textarea.target").val();
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: 'http://localhost/Forepost/php/real_time_comment.php', // the url where we want to POST
data: {
posta_id: posta_id,
tetxarea1: tetxarea1
}, // our data object
dataType: 'json', // what type of data do we expect back from the server
success: (function (response) {
display_the_comment(jQuery.parseJSON(response));
console.log(response);
}),
error: function () {
alert("oops something went wrong");
// oops something went wrong
}
});
//FUNCTION TO DISPLAY COMMENT FROM DATABASE
function display_the_comment(response) {
var comment_string = " ";
comment_string += "<li class='indiv_cmnts'>";
comment_string += "<span class='user_fname2'>'" + response.f_name + "'</span>";
comment_string += "<div class='my_msg'>'" + esponse.my_comment + "'</div>";
comment_string += "<img class='user_proff' src='" + response.profile_img + "'/>";
comment_string += "<span class='time_cmnts'>'" + response.my_comment_date + "'</span>";
//comment_string += "<span class='fa_reply'><i class='fa fa-reply' aria-hidden='true'></i> reply</span>";
comment_string += "</li>";
$("ul.comenting2").prepend(comment_string);
}
//FUNCTION TO DISPLAY COMMENT FROM DATABASE
});
});
});
i am trying to display the list to unordered lis with the class "comenting2"
change your code from
$("ul.comenting2").prepend(comment_string);
to
$("ul.comenting2").prepend($(comment_string));
Your response value already is an object since jquery parses it automatically (you put json as datatype). You are trying to json-parse an object, of course that has illegal characters.
Yes. To make it easier to understand the problem. I believe it would be great if you also supplied the sample of your JSON response. It is usually caused by bad JSON format.
Okay. Got your sample JSON response.
Try to change your code into:
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: 'http://localhost/Forepost/php/real_time_comment.php', // the url where we want to POST
data: {
posta_id: posta_id,
tetxarea1: tetxarea1
}, // our data object
dataType: 'json', // what type of data do we expect back from the server
success: (function (response) {
display_the_comment(eval('('+response+')'));
console.log(response);
}),
error: function () {
alert("oops something went wrong");
// oops something went wrong
}
});
//FUNCTION TO DISPLAY COMMENT FROM DATABASE
function display_the_comment(response) {
var comment_string = " ";
comment_string += "<li class='indiv_cmnts'>";
comment_string += "<span class='user_fname2'>‘" + response.f_name + "’</span>";
comment_string += "<div class='my_msg'>‘" + esponse.my_comment + "’</div>";
comment_string += "<img class='user_proff' src='" + response.profile_img + "'/>";
comment_string += "<span class='time_cmnts'>‘" + response.my_comment_date + "’</span>";
//comment_string += "<span class='fa_reply'><i class='fa fa-reply' aria-hidden='true'></i> reply</span>";
comment_string += "</li>";
$("ul.comenting2").prepend(comment_string);
}
Please noted the changes at ajax success and function display_the_comment(response)

Update: How do I dynamically populate a list with data from a JSON file?

I want to dynamically populate a list with elements from a JSON file. The idea is to switch the test_ID in the list with the actual object from the JSON file. How do I do this?
JSON file
[
{
"id": "a",
"test": "Java",
"testDate": "2016-08-01"
},
{
"id": "b",
"test":"JavaScript",
"testDate": "2016-08-01"
}
]
jQuery
$(function(){
$.ajax({
type : 'GET',
url : 'json/data.json',
async : false,
beforeSend : function(){/*loading*/},
dataType : 'json',
success : function(result) {
});
$("#test_ID").empty(); //emtpy the UL before starting
$.each(arr_json, function(i, v, d) {
$("#test_ID").append("<li id='" + v.id +'" + v.test +"' >" + v.testDate + "<li>");
});
}
});
});
HTML
<li id="test_ID"></li>
I do receive a couple of errors. The Line:
$("#test_ID").append("<li id='" + v.id +'" + v.test +"' >" + v.testDate + "<li>");
gives the following error: invalid number of arguments and unclosed String literal.
I am also unsure of how to identify to specific elements in the JSON file.
Update
I would like if the list element was in this format "Java 2016-08-01" and "JavaScript 2016-08-01". Thank you!
You have a couple of errors in your javascript. See the corrected version below:
$(function(){
$.ajax({
type : 'GET',
url : 'json/data.json',
async : false,
beforeSend : function(){/*loading*/},
dataType : 'json',
success : function(result) {
$("#test_ID").empty(); //emtpy the UL before starting
// **************** correction made to the line below ***********************
$.each(result, function(i, v, d) {
// **************** correction made to the line below ***********************
$("#test_ID").append('<li id="' + v.id + '">' + v.test + ' ' + v.testDate + '</li>'); // correction made here
});
}
});
});
I did a quick fiddle. I don't quite understand what you're doing with v.test being unmarked inside the HTML tags so I did not include it. I used minimal JQuery to avoid complexity.
https://jsfiddle.net/ndx5da97/
for (record in data) {
$("#test_ID").append('<li id="' + data[record].id + '">' + data[record].testDate + '</li>');
}
Hope this helps!

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

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);
});
}

Categories

Resources