This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 7 years ago.
I'm new to using JSON and Javascript, but I am trying to sort various values of the JSON file provided by Reddit. In the console, I do see the array and the JSON values from the console.log(posts) print. However, the console.log(posts.length) statement returns 0 and nothing is displayed to the screen, which I suspect is due to how I am storing and/or retrieving the JSON values in the array.
var minVotes = 5;
var subreddit = "askreddit";
var posts = [];
//Retrieve JSON from Reddit using JQuery
$.getJSON("https://www.reddit.com/r/" + subreddit + "/rising.json?limit=50", function foo(result) {
$.each(result.data.children.slice(0, 50), function(i, post) {
if (post.data.ups > minVotes) {
//Push JSON data to array to be sorted later
posts.push(post.data);
}
})
})
//Sort the array
posts.sort(function(a, b) {
return parseInt(a.data.ups - a.data.num_comments) - parseInt(b.data.ups - b.data.num_comments);
});
console.log(posts);
console.log(posts.length); //returns 0 ???
//Display the content, which doesn't work
for (var i = 0; i < posts.length; i++) {
$("#reddit-content").append('<br>' + "Title: " + posts[i].title);
$("#reddit-content").append('<br>' + "Url: " + posts[i].url);
$("#reddit-content").append('<br>' + "Upvotes: " + posts[i].ups);
$("#reddit-content").append('<br>' + "Comments: " + posts[i].num_comments);
$("#reddit-content").append('<hr>');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="reddit-content"></div>
It's because of the async nature of $.getJSON. If you sort the array inside the response handler it works fine.
You also had another issue in your sort with accessing the property values. I don't believe you need to parseInt either as JSON.parse will return those values as numbers already.
var minVotes = 5;
var subreddit = "askreddit";
//Retrieve JSON from Reddit using JQuery
$.getJSON("https://www.reddit.com/r/" + subreddit + "/rising.json?limit=50", function foo(result) {
var posts = [];
$.each(result.data.children.slice(0, 50), function(i, post) {
if (post.data.ups > minVotes) {
//Push JSON data to array to be sorted later
posts.push(post.data);
}
});
//Sort the array
posts.sort(function(a, b) {
return parseInt(a.ups - a.num_comments) - parseInt(b.ups - b.num_comments);
});
console.log(posts);
console.log(posts.length);
//Display the content, which doesn't work
for (var i = 0; i < posts.length; i++) {
$("#reddit-content").append('<br>' + "Title: " + posts[i].title);
$("#reddit-content").append('<br>' + "Url: " + posts[i].url);
$("#reddit-content").append('<br>' + "Upvotes: " + posts[i].ups);
$("#reddit-content").append('<br>' + "Comments: " + posts[i].num_comments);
$("#reddit-content").append('<hr>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="reddit-content"></div>
Related
This question already has an answer here:
JQuery clear HTML table and insert new rows
(1 answer)
Closed 3 years ago.
$("#artistButton").on('click', function () {
var artist = $("#artistSearch").val().trim()
var queryURL = "https://rest.bandsintown.com/artists/" + artist + "/events?app_id=test&date=upcoming" + artist + "?app_id=test";
console.log(artist)
$.ajax({
url: queryURL,
method: "GET"
}).then(function (response) {
var imageURL = response[0].artist.image_url;
var image = $("<img id='pictureSize'>")
var artistName = response[0].artist.name
console.log(response)
$("#artistName").html(artistName)
image.attr('src', imageURL)
$("#artistImage").html(image)
$("#venue").html(response[125].venue.name)
for (var i = 0; i < response.length || 5; i++) {
var time = moment(response[i].datetime).format("MMM Do, hh:mm");
var venueName = response[i].venue.name
var city = response[i].venue.city;
var region = response[i].venue.region
if (i == 5) {
break;
}
$(".tableData").before($("<tr><td>" + venueName + "</td>" + "<td>" + city + ', ' + region + "</td>" + "<td>" + time + "</td></tr>"))
}
});
$(".tableData").val("");
})
Wanted to answer my own question in case someone had the same issue but i simply added $("#concertInfo").find("td").remove(); after my ajax call and it will remove all table data!
You can use empty or remove function to set the table content before adding new ones.
Empty: "Remove all child nodes of the set of matched elements from the DOM."
Remove: "Remove the set of matched elements from the DOM."
I'm trying to loop through an array using contains, but even if the value isnt it there it still appears true. The array is a list of checkboxes
function CheckBoxLogic(QId, Valuearray, UnCheckedValueArray) {
var CheckedChildArray = Valuearray;
var UnCheckedChildArray = UnCheckedValueArray;
$('.AnswerFunctions').each(function () {
//Get ParentID from child control
var ParentQuestionId = $(this).attr('ParentQuestionId');
//Get ParentValue from child control
var ParentQuestionValue = $(this).attr('ParentQuestionValue');
var QuestionId = $(this).attr('QuestionId');
if (ParentQuestionId === QId) {
if ($(CheckedChildArray + ":contains('" + ParentQuestionValue + "')")) {
$('#' + QuestionId + '-Question').removeClass('d-none');
}
//if ($(UnCheckedChildArray + ":contains('" + ParentQuestionValue + "')")) {
// $('#' + QuestionId + '-Question').addClass('d-none');
// };
}
});
}
}
That's not how you loop through an array. (At its simplest, what exactly do you expect [] + ":contains('" to be? You can't meaningfully concatenate a string and an array like that.)
If you want to check if an array contains a value, you can use the includes method. For example:
if (CheckedChildArray.includes(ParentQuestionValue)) {
$('#' + QuestionId + '-Question').removeClass('d-none');
}
I am using node.js to develop firebase cloud functions. I need to connect to google maps api to get the distance between two Latlng points. I am making an https get request and receiving a response with a JSon object. The problem is that the received object is empty with a status: INVALID_REQUEST in most cases. However, in some rare cases it returns the desired value. I have tried the path and host of my request on the browser and the json object is retrieved successfully there. I do not know exactly where my problem is. Is it in the callback? the path? something else?
I am giving my code and the output of it.
My code is :
function getStatusCode(options, callback) {
https.get(options, function(http_res) {
var data = "";
console.log('inside the https request');
http_res.on("data", function (chunk) {
data += chunk;
console.log("I am reading the data");
console.log(data);
// callback(http_res.statusCode, data)
});
http_res.on("end", function () {
console.log("I am in the ON_END listener");
console.log('data contains: >> ' + data + ' I am in the ONEND listener')
callback(http_res.statusCode, data)
});
});
}
and I am calling it as follows:
console.log('startingPoints ' + startingPoints);
console.log('lat and lng are: '+lat+" , "+lng);
var options = {
host: 'maps.googleapis.com',
path: '/maps/api/distancematrix/json?units=imperial&origins='+startingPoints+'&destinations='+lat+','+lng+'&key=MY_GOOGLEMAPSAPI_KEY',
method: get
};
getStatusCode(options, function(statusCode, data){
console.log('The status code is : '+statusCode);
console.log('and data is : '+data);
// parsing json object:
jData = JSON.parse(data);
rows = jData.rows;
console.log('the length of the rows array is >> ' + rows.length + ', the length of the techs array is >> ' + techs.length);
min = -1;
for(var i = 0; i < rows.length; i++){
console.log('the array of techs + the equivalent values of the array of row >>' + techs[i] + ' and ' + rows[i].elements[0].distance.value);
if( min < 0 || rows[i].elements[0].distance.value < rows[min].elements[0].distance.value)
min = i;
console.log('minimum distance tech in the loop; the id is >> ' + techs[min] + ", and the distance is >> " + rows[min].elements[0].distance.value);
}
console.log('the min value before return is >> ' + min);
and the retrieved json object is:
{
"destination_addresses" : [],
"origin_addresses" : [],
"rows" : [],
"status" : "INVALID_REQUEST"
}
any idea please,,
I have found a solution. precisely, found my problem. The problem was not within google-map-api. It was with assignment of the starting_points variable.
I'm new to jquery and a I've got the problem as mentioned in the title.
My controller code looks like:
[HttpPost]
public JsonResult getProjectList()
{
List<Project> projectList = new List<Project>();
foreach (IML.ProjectInfo pr in getProjectArray())
{
Project x = new Project(pr.Name, pr.ID, pr.OwnerID, pr.CreatedBy, pr.CreatedAt, "", pr.Deleted, pr.Closed);
projectList.Add(x);
}
return Json(projectList.ToArray());
}
When I check the projectList under debugger mode it has 6 elements.
In my webpage I have the following ajax call:
$.ajax({
url: '#Url.Action("getProjectList")',
type: "POST",
//enumerowanie projektów
success: function (data) {
projekty = data;
var wyswietl ="<table><tbody>";
var tabelka = "";
var wybranyProjekt;
alert($.data.length);//this alert tells me that data.length is 3
for (i = 0; i < 6; i++)//even if $.data.length is 3 the data[i].Name holds values for 6 elements
{
tabelka += "<tr class=\"enumeracjaProj\" id=\"" + i
+ "\"><td class=\"projekty\" id=\"" + i + "\"> " + data[i].Name + " </td></tr>"
}
wyswietl += tabelka;
wyswietl += "</tbody></table>";
$('#projekty_div').append(wyswietl);
})
Even if I Post an array of 6 elements ajax result tell me that its length is 3. If I go over it in loop which was 6 iterations hard-coded I get properly displayed name.
Small correction, You should change your alert($.data.length); to alert(data.length);
$.data is jQuery function and your data is response result
So, using parse.com, I'm doing some nested queries... basically, getting an object and then retrieving its relations and doing some operations.
pageQuery.find({
success: function (results) {
var pages = [];
for (var result = 0; result < results.length; result++) {
var resArrayLength = pages.push(results[result].toJSON());
var indexOfLastPush = resArrayLength - 1;
console.log("resArrayLength = " + resArrayLength);
pages[indexOfLastPush].scrapeRules = new Array();
console.log("index of last push set to " + indexOfLastPush);
var relation = results[result].relation("RulesForPage");
//get the related scrape rules
relation.query().find({
success: function (rules) {
console.log("Found " + rules.length + " rules");
for (var i = 0; i < rules.length; i++) {
console.log("rule index = " + i);
console.log("Found rule " + rules[i].id);
pages[indexOfLastPush].AllRules = new Array();
pages[indexOfLastPush].scrapeRules.push(rules[i].id);
console.log("pushed rule " + rules[i].get("name") + " to page at index " + indexOfLastPush);
}
}
});
}
The problem I am seeing is that I am trying to indexOfLastPush to track an array index I need, but that value has changed by the time the call back has happened.
How can I pass it to the "success" callback so I have the index I need?
UPDATE: Thanks to #cggaurav for the excellent tip. Why does it seem like the answer to every JavaScript problem is to wrap your code in an anonymous function?
You have to have what is called a closure or an anonymous function for every relation.query() you make. See "More on lexical scoping" | http://mark-story.com/posts/view/picking-up-javascript-closures-and-lexical-scoping