Only 1 result from JSON loop - javascript

Could somebody explain how come this is only returning 1 result (there should be 4). Its only returning the most recent post title, where I would like to be getting all the post titles in the category (ID: 121) which in this case is four.
<script type="text/javascript">
var posturl = "http://www.tropical420.com/api/get_posts/?posts_per_page=-1";
$.ajax({
type: 'GET',
url: posturl,
complete: function(){
},
success: function (data) {
var response = data; //JSON.parse(data);
//loop through posts
for(var i = 0; i != response.posts.length; i++) {
//get each element in the array
var post = response.posts[i];
// post vars
var postTitle = post.title;
var postContent = post.content;
var postCategory = post.categories[i].id;
// output stuff so we can see things
if (postCategory == '121') {
$("#post").append(postTitle + "<br />").trigger('create');
}
}
},
error:function (xhr, ajaxOptions, thrownError) {
alert("Error");
}
});
</script>
<div id="post"></div>

The problem you have is that you aren't iterating through all the categories, instead you are just referring with the same index as to your posts array. You should iterate all the categories through like this
var postCategories= post.categories;
for (var postCategoryIndex in postCategories)
{
var postCategory = postCategories[postCategoryIndex].id;
if (postCategory == '121') {
$("#post").append(postTitle + "<br />").trigger('create');
}
}

The JSON returned does indeed include 49 posts, and you would know that if you had tried console.log(response.posts.length)
sanfor has pointed out the logic error in your code, but your whole callback function can be written much more cleanly, like this:
function (data) {
data.posts.filter(function (post) {
return post.categories.filter(function (cat) { return cat.id === '121'; });
}).forEach(function (post) {
$("#post").append(post.title + "<br />").trigger('create');
});
}

Related

Fill array by multiple AJAX requests, then pass array to another function

(My solution below)
I have several HTML elements with class .canvas-background of which information is stored in the database. I want to get the information of each element and process it via JavaScript. But somehow I can't pass the response of the AJAX request to another function. Here is what I've tried:
function initTabs() {
var tabs = loadTabInformation();
console.log(tabs); // (1)
// do something else
}
function loadTabInformation() {
var requests = new Array();
var tabs = new Object();
var counter = 0;
$(".canvas-background").each(function () {
var tabNumber = $(this).data("tab-number");
var request = $.ajax({
type: 'POST',
url: '../db/GetTabInformation.ashx',
data: String(tabNumber),
dataType: 'json',
contentType: 'text/plain; charset-utf-8'
})
.done(function (response) {
tabs[counter++] = response;
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("request error in loadTabInformation()");
console.log(textStatus);
console.log(errorThrown);
});
requests.push(request);
});
$.when.apply($, requests).done(function () {
console.log(tabs); // (2)
return tabs;
});
}
At (1) I get undefined, but at (2) everything seems to be alright.
THE SOLUTION:
Thanks to the answer and the link in the comment #Kim Hoang provided I got this working. The clue seemed to put the done() function in the calling function, that is initTabs() in my case. Another thing I got wrong was to try to do the logic that should be executed after the AJAX requests had finished outside the done callback function. They must be inside (makes sense, if you think about it). And a lot of conosle output helped, to see what function returns what kind of object.
function initTabs() {
var tabInfoRequest = loadTabInfo();
tabInfoRequest[0].done(function() {
var results = (tabInfoRequest[1].length > 1) ? $.map(arguments, function(a) { return a[0]; }) : [arguments[0]];
for (var i = 0; i < results.length; i++) {
// do something with results[i]
}
});
}
function loadTabInfo() {
var tabNumbers = new Array();
$(".canvas-background").each(function () {
tabNumbers.push($(this).data("tab-number"));
});
var requests = $.map(tabNumbers, function (current) {
return $.ajax({
type: 'POST',
url: '../db/GetTabInformation.ashx',
data: String(current),
dataType: 'json',
contentType: 'text/plain; charset-utf-8'
});
});
var resultObject = new Object();
resultObject[0] = $.when.apply($, requests);
resultObject[1] = requests;
return resultObject;
}
Note: I only did the resultObject-thing because I needed the array requests in the initTabs() function.
Thank you very much for helping me!
You do not return anything in loadTabInformation, so of course you will get undefined. You should do it like this:
function loadTabInformation() {
...
return $.when.apply($, requests);
}
function initTabs() {
loadTabInformation().done(function (tabs) {
console.log(tabs); // (1)
// do something else
});
}

Add Property dynamically to the JSON array

I would like to two add property Id and ButtonId to the exisiting json result. I have pasted the below js code for reference and I would like to pass the jsonresult to MVC controller. As of now it returns null. please help to proceed. Thanks.
my final result should look like this
json{"Groups":{"Id":"2","ButtonId":"1142","1186","1189"},
{"Id":"3","ButtonId":"1171","1173","1174","1175","1176","1187"},
{"Id":"4","ButtonId":"1177","1178","1179"}} etc..
var btnlist = {Groups: {Id:"", ButtonId: ""}};
$.each($(".buttonData"), function (index, value) {
var values = value.id.split(':');
grpid = values[0].split('-')[1];
btnid = values[1].split('-')[1];
console.log('grpid=' + grpid + ' btnid=' + btnid);
if (typeof (btnlist['Groups'][grpid]) == 'undefined') {
btnlist['Groups'][grpid] = [];
}
btnlist['Groups'][grpid].push(btnid);
});
$.ajax({
type: "POST",
url: "#Url.Action("Home", "Menu")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(btnlist) ,
success: function (result) {
console.log('json' + JSON.stringify(btnlist));
console.debug(result);
},
error: function (request, error) {
console.debug(error);
}
});
This is the json result before pushing into the multidimensional array
The json result, where the properties Id and ButtonId is inserted behind.
null result passed to the controller
With assistance of my colleague, the desired output is as below. This is for other programmers who face similar issue with JSON array. Thanks.
var btnlist = [];
btngrps = $('.btn-sort-container');
$.each(btngrps, function(k, v) {
btnarr = {};
gid = $(this).attr('id');
grpid = gid.split('-')[1];
btnarr.Id = gid.split('-')[1];
btnobjs = $(v).find('.buttonData');
if (btnobjs.length) {
btnarr['btnId'] = [];
$.each(btnobjs, function(bk, bv) {
btnid = $(bv).attr('id').split('-')[2];
btnarr['btnId'].push($(bv).attr('id').split('-')[2]);
});
console.debug(btnarr);
btnlist.push(btnarr);
}
});
console.debug(btnlist);
Output on console
: http://i.stack.imgur.com/oJ3Dy.png

loop for fetching json data in html [duplicate]

On the jQuery AJAX success callback I want to loop over the results of the object. This is an example of how the response looks in Firebug.
[
{"TEST1":45,"TEST2":23,"TEST3":"DATA1"},
{"TEST1":46,"TEST2":24,"TEST3":"DATA2"},
{"TEST1":47,"TEST2":25,"TEST3":"DATA3"}
]
How can I loop over the results so that I would have access to each of the elements?
I have tried something like below but this does not seem to be working.
jQuery.each(data, function(index, itemData) {
// itemData.TEST1
// itemData.TEST2
// itemData.TEST3
});
you can remove the outer loop and replace this with data.data:
$.each(data.data, function(k, v) {
/// do stuff
});
You were close:
$.each(data, function() {
$.each(this, function(k, v) {
/// do stuff
});
});
You have an array of objects/maps so the outer loop iterates over those. The inner loop iterates over the properties on each object element.
You can also use the getJSON function:
$.getJSON('/your/script.php', function(data) {
$.each(data, function(index) {
alert(data[index].TEST1);
alert(data[index].TEST2);
});
});
This is really just a rewording of ifesdjeen's answer, but I thought it might be helpful to people.
If you use Fire Fox, just open up a console (use F12 key) and try out this:
var a = [
{"TEST1":45,"TEST2":23,"TEST3":"DATA1"},
{"TEST1":46,"TEST2":24,"TEST3":"DATA2"},
{"TEST1":47,"TEST2":25,"TEST3":"DATA3"}
];
$.each (a, function (bb) {
console.log (bb);
console.log (a[bb]);
console.log (a[bb].TEST1);
});
hope it helps
For anyone else stuck with this, it's probably not working because the ajax call is interpreting your returned data as text - i.e. it's not yet a JSON object.
You can convert it to a JSON object by manually using the parseJSON command or simply adding the dataType: 'json' property to your ajax call. e.g.
jQuery.ajax({
type: 'POST',
url: '<?php echo admin_url('admin-ajax.php'); ?>',
data: data,
dataType: 'json', // ** ensure you add this line **
success: function(data) {
jQuery.each(data, function(index, item) {
//now you can access properties using dot notation
});
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("some error");
}
});
Access the json array like you would any other array.
for(var i =0;i < itemData.length-1;i++)
{
var item = itemData[i];
alert(item.Test1 + item.Test2 + item.Test3);
}
This is what I came up with to easily view all data values:
var dataItems = "";
$.each(data, function (index, itemData) {
dataItems += index + ": " + itemData + "\n";
});
console.log(dataItems);
Try jQuery.map function, works pretty well with maps.
var mapArray = {
"lastName": "Last Name cannot be null!",
"email": "Email cannot be null!",
"firstName": "First Name cannot be null!"
};
$.map(mapArray, function(val, key) {
alert("Value is :" + val);
alert("key is :" + key);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
if you don't want alert, that is u want html, then do this
...
$.each(data, function(index) {
$("#pr_result").append(data[index].dbcolumn);
});
...
NOTE: use "append" not "html" else the last result is what you will be seeing on your html view
then your html code should look like this
...
<div id="pr_result"></div>
...
You can also style (add class) the div in the jquery before it renders as html
I use .map for foreach. For example
success: function(data) {
let dataItems = JSON.parse(data)
dataItems = dataItems.map((item) => {
return $(`<article>
<h2>${item.post_title}</h2>
<p>${item.post_excerpt}</p>
</article>`)
})
},
If you are using the short method of JQuery ajax call function as shown below, the returned data needs to be interpreted as a json object for you to be able to loop through.
$.get('url', function(data, statusText, xheader){
// your code within the success callback
var data = $.parseJSON(data);
$.each(data, function(i){
console.log(data[i]);
})
})
I am partial to ES2015 arrow function for finding values in an array
const result = data.find(x=> x.TEST1 === '46');
Checkout Array.prototype.find() HERE
$each will work.. Another option is jQuery Ajax Callback for array result
function displayResultForLog(result) {
if (result.hasOwnProperty("d")) {
result = result.d
}
if (result !== undefined && result != null) {
if (result.hasOwnProperty('length')) {
if (result.length >= 1) {
for (i = 0; i < result.length; i++) {
var sentDate = result[i];
}
} else {
$(requiredTable).append('Length is 0');
}
} else {
$(requiredTable).append('Length is not available.');
}
} else {
$(requiredTable).append('Result is null.');
}
}

Use Parse Query in then() when using Cloud Code

I can’t seem to get this simple Parse query to work in my cloud code then() it works outside of this but when i place the code inside of this then function nothing happens. The variables are just placeholders for now in terms of testing but i have the default TestObject class you get when you start Parse from the beginning but for some reason it just keeps on returning nothing.
Here is the full function that i am currently using.
// Function which will get the data from all the links passed into the function
Parse.Cloud.define("myNews", function (request, response) {
var promises = _.map(import_io_keys, function (news_api_key) {
return Parse.Cloud.httpRequest({
method: 'GET',
url: "https://api.import.io/store/connector/" + news_api_key + "/_query?input=webpage/url:https%3A%2F%2Fwww.designernews.co%2Fnew&&_apikey=xxxxxxxxxxxxxxxxxx",
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
}).then(function (httpResponse) {
result = JSON.parse(httpResponse.text);
var success = false;
var news_icon = "";
var news_source_name = "";
var query = new Parse.Query("TestObject");
query.find({
success: function(results) {
success = true;
news_icon = results[0].get("foo");
news_source_name = results[0].get("foo");
response.success("done" + news_icon);
},
error: function() {
success = false;
response.error("Query lookup failed");
}
});
for (var story in result.results) {
if(story.length > 0){
if (story["article_link/_text"] !== "" && story["article_link"] !== "" && story["article_time"] !== "") {
if(success){
// Do the stuff later
}
}
}
}
});
});
Parse.Promise.when(promises).then(function () {
console.log("Got all the stories");
response.success(newsJsonData);
}, function () {
response.error("No stories");
console.log("API KEY IS: " + request.params.keys);
});
});

JQuery AutoComplete with JSON Result Not Working

I am using a JQuery autocomplete to display a list of available courses. I am doing a post to get a list of Courses from the server, I manipulate the data to be in the expected format, and I pass it to the autocomplete function. The problem is that it does not work unless I hard copy and paste the values newSource and paste them into source.
The variable newSource = ["Enc1001","ENC1002","Enc1003","ENC1101"....etc].
The ajax post to get the data from the server
//Auto complete for search box
$('#AdditionalSearch').on('input', function () {
var source = [];
var inputValue = $('#AdditionalSearch').val();
if (inputValue !== '') { //the value is not empty, we'll do a post to get the data.
url = "/Course/CourseSearch";
$.ajax({
method: 'POST',
dataType: 'json',
contentType: 'application/json',
cache: false,
data: JSON.stringify({ "searchCourseValue": inputValue }),
url: url,
success: function (data) {
if (data.Ok) {
var myData = JSON.parse(data.data);
var newSource = '[';
$.each(myData.ResultValue, function (index, item) {
if ((myData.ResultValue.length -1) == index)
newSource += '"' + item.Name+'"';
else
newSource += '"'+ item.Name + '",';
});
newSource += "]";
console.log(newSource);
source = newSource;
}
setNameAutoComplete(source);
},
error: function (jqXHR) {
console.log(error);
}
});
} else { //The user either delete all the input or there is nothing in the search box.
//The value is empty, so clear the listbox.
setNameAutoComplete(source);
}
});
//Passing the source to the auto complete function
var setNameAutoComplete = function (data) {
console.log(data);
$('#AdditionalSearch').autocomplete({
source: data
});
}
Is there something that I am missing here?
When you literally paste newSource = ["Enc1001","ENC1002","Enc1003","ENC1101"....etc]in your code, you are building an array object. However, in your success method, you are building a string (the string-representation of that same object). What you want to be doing is build an actual array in stead.
...
success: function (data) {
if (data.Ok) {
var myData = JSON.parse(data.data);
var newSource = [];
$.each(myData.ResultValue, function (index, item) {
newSource.push(item.Name);
});
console.log(newSource);
source = newSource;
}
setNameAutoComplete(source);
},
...

Categories

Resources