Code not adding object to an array - javascript

I'm trying to add a set of objects that have been retrieved from a JSON file into an array. I've tried using push but the result is the same. The length value of the array remains 0. What am I doing wrong? The JSON parses fine as I can get the values during the loop.
<script type="text/javascript">
//my array
var myArray = new Array();
function performSearch(){
var url = "http://myjsonurl...";
var counter = 0;
$.getJSON(url, function(response){
$.each(response.data.people, function() {
//p is the the object to add to the array
var p = new person(this.name, this.age);
//tried using myArray.push instead of having a counter, but
//I get the same length of 0.
myArray[counter] = p;
counter++;
});
});
//always returns 0
alert(myArray.length);
}
...
</script>

getJSON() is an asynchronous function. It only starts to fetch the data when you call it, and it calls the given function only after it has loaded it. So you call the alert before anything is fetched. You should have the alert right after the .each() function.

Ajax is asynchronous. Whatever depends on the JSON needs to happen in the callback.
function performSearch()
{
var url = "http://myjsonurl...";
$.getJSON(url, function(response)
{
var myArray = $.map(response.data.people, function()
{
return new person(this.name, this.age);
});
alert(myArray.length);
});
//always returns 0
alert(myArray.length);
// that's because this code executes before the $.getJSON callback does
}

You are returning the array before you put the objects in it.
The callback function used in the getJSON method doesn't run right away, it runs when the response arrives. As two methods can't run at the same time, you will always have exited your function before the callback function can run.
You can access the result inside the callback function:
<script type="text/javascript">
function performSearch(){
var url = "http://myjsonurl...";
$.getJSON(url, function(response){
var myArray = [];
$.each(response.data.people, function() {
var p = new person(this.name, this.age);
myArray.push(p);
});
alert(myArray.length);
});
}
</script>

<script type="text/javascript">
//my array
var myArray = new Array();
var counter = 0;
function performSearch(){
var url = "http://myjsonurl...";
$.getJSON(url, function(response){
$.each(response.data.people, function() {
//p is the the object to add to the array
var p = new person(this.name, this.age);
//tried using myArray.push instead of having a counter, but
//I get the same length of 0.
myArray[counter] = p;
counter++;
alert(myArray.length);
});
});
}
...
</script>

Related

getting data from file.txt and returning it with an array

i have file.txt
apple <--line 1
banana <--line 2
and this is my script
url = 'file.txt';
homelists = [];
$.get(url, function(data) {
var lines = data.split("\n"); <--i want to split it by line
$.each(lines, function(n ,urlRecord) {
homelists.push(urlRecord); <--add it to my homelists array
});
});
console.log(homelists); <-- returns array
console.log(homelists[0]); <--undefined
my problem is i cant get the inside value of homelists
how can i get homelists[0] or homelists[1]..(javascript or jquery(preferrable))
Javascript/Jquery ajax is an Async call meaning the code $.get and console.log on your example will be executed parallelly (immediate or the same times), so to parse the result of your file.txt, you need to do it inside the function (which will be executed after ajax called is done).
url = 'file.txt';
homelists = [];
$.get(url, function(data) {
var lines = data.split("\n");
$.each(lines, function(n ,urlRecord) {
homelists.push(urlRecord);
});
console.log(homelists);
console.log(homelists[0]);
});
I know this is too simple answer and may sound stupid to others but i have an idea!
why not store in the session the $.get data
url = 'file.txt';
$.get(url, function(data) {
localStorage['homelists'] = data;
});
then assign a variable to that session
homelists = localStorage['homelists'];
then make the session = null
localStorage['homelists'] = null
when you do console.log outside
console.log(homelists); <-returns string which you can manipulate to turn it into array
console.log(localStorage['homelists']); <-returns null
I dont know yet what could be the bad side/effect of this with my project.. any idea?
Since you are using jQuery, It would be better if you use AJAX. !
const ImportData = function(file){
let arrayData = undefined;
$.ajax({
url: file,
type: 'GET',
error: (err) => { throw new Error(err) },
success: ( data ) => {
arrayData = MakeArray( data );
//Do whatever you want here
console.log( arrayData );
}
});
}
const MakeArray = function(plaintext){
const array = [];
plaintext.split('\n').forEach( (line) => {
line = line.trim();
array.push( line );
} );
return array;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
const file = "https://www.w3.org/TR/PNG/iso_8859-1.txt";
document.addEventListener('DOMContentLoaded', function(){
ImportData( file );
});
</script>

Put XMLHttprequest results into one string

I'm trying to get my array of URL's to run through a JQuery .get function to get the site's source code into one string outside of the function. My code is below.
var URL = ["http://website.org", "http://anothersite.com"];
var array = URL.map(function(fetch) {
var get = $.get(fetch, function(sourcecode) {
sourcecode = fetch;
}
I need the sourcecode variable to be the combination of source code on all of the URLs in the array.
You need to put a variable outside of the function, something like this data variable below and append to it with +=:
var URL = ["http://website.org", "http://anothersite.com"];
var array = URL.map(function(fetch) {
var data = null;
var get = $.get(fetch, function(sourcecode) {
data += fetch;
}
}
Try this like,
var URL = ["http://website.org", "http://anothersite.com"];
var array = $(URL).map(function(fetch) {
var data='';
$.ajax({
url:fetch,
async:false,
success : function(d){
data=d;
}
});
return data;
}).get();
Since you're using jQuery, I suppose that jQuery.each() may be a better way to iterate over the array.
var URL = ["http://website.org", "http://anothersite.com"];
var str = [];
$.each(URL, function(index, fetch) {
$.get(fetch, function(sourcecode) {
str.push(sourcecode); // if you want an array
})
});
str.join(''); // if you want a string
console.log(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

$.getJson from X files by a LOOP and STORE each in a VARIABLE using JAVASCRIPT

I need to $.getJSON from files by using a loop on Javascript:
///////JS.serial =[156,256] but i can have more than 2 values//
var Electricity = {
refreshJson : function() {
for(var i=0; i<JS.nbre_serials;i++)
url = 'json/kw/kw_'+JS.serials[i]+'.json';
$.getJSON(url, function(data){
// ???
Electricity.processConsumption(data_156,data_256);
});
},
I would like store each object return in a variable (i.e. var datas_156 ).
You can use $.when, so you can call Electricity.processConsumption when all the results are ready. That is possible because $.getJSON returns a promise compatible object.
refreshJson : function() {
var promises = [];
for(var i=0; i<JS.nbre_serials;i++){
var url = 'json/kw/kw_'+JS.serials[i]+'.json';
promises.push($.getJSON(url));
}
$.when.apply($, promises)
.done(function(data_156, data_256){
Electricity.processConsumption(data_156,data_256);
})
.fail(function() {
//handle errors
});
}
In the example $.when.apply($, promises) is called that way because $.when won't accept an array of promises, but a variable number of parameters.
The same way you could call Electricity.processConsumption, so you don't have to change the code every time a new "serial" is added.
refreshJson : function() {
var promises = [];
for(var i=0; i<JS.nbre_serials;i++){
var url = 'json/kw/kw_'+JS.serials[i]+'.json';
promises.push($.getJSON(url));
}
$.when.apply($, promises)
.done(function(){
Electricity.processConsumption.apply(Electricity,arguments);
})
.fail(function() {
//handle errors
});
}
And your processConsumption function might be something like:
//somewhere in the Electricity class
processConsumption: function(){
var data_156 = arguments[0];
var data_256 = arguments[1];
//do stuff
}

Populating array with response from nested AJAX calls

I have an array that I would like to fill with responses from AJAX calls like so:
var dict = [];
function fillArray(){
$.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++){
$.get("https://api.twitch.tv/kraken/streams" , function(data){
dict[data.key] = data;
});
});
}
function doStuff(){
// dict is empty or undefined here
}
How would I fill dict with objects so that I could retrieve them inside doStuff()? Currently, I am able to insert stuff into dict but when I try accessing dict outside the fillArray() function, I get an empty dict variable since I'm assuming the GET call is asynchronous and doesn't happen until after all the JS code has executed...
So, dict is an object that has no push method. You'd need dict=[]; If you had to have {}, then you'd need key:value pairs to populate it, such as:
dict[key] = value;
You are going to have to keep track of the number of calls that you are doing in that for loop and fire a callback function once they are all complete. I'm not totally confident about your current solution, with calling an indefinite amount of ajax requests, but I also don't fully understand the scope of your problem or the server that you're talking to.
So basically you will have to do something like this with what you have currently:
var dict = [],
requestsCompleted = 0;
function dictFilled() {
// do something with your dict variable;
}
function fillArray(){
$.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++){
$.get("https://api.twitch.tv/kraken/streams" , function(data){
dict[data.key] = data;
requestsCompleted++;
if (requestsCompleted === phpReturnVal.length) {
dictFilled();
}
});
});
}
This haven't been tested, but basically you will have to define a function that will have access to the array that you are filling and call it once all you asynchronous requests finish successfully. For tasks like this though I recommend you take a look at jQuery's Deferred API. There is always a chance that one of those requests will fail and your application should know what to do if that happens.
I'm assuming the GET call is asynchronous and doesn't happen until
after all the JS code has executed...
Appear correct.
Try
var dict = [];
function fillArray() {
// return jQuery promise object
return $.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++) {
// call same `url` `phpReturnVal.length` times here ?,
// returning same `data` response at each request ?,
// populating, overwriting `dict` with same `data.key` property ?
$.get("https://api.twitch.tv/kraken/streams" , function(data) {
dict[data.key] = data;
});
}; // note closing `}` at `for` loop
// return value
return dict
});
}
function doStuff(data) {
// `data`:`dict`, promise value returned from `fillArray`
console.log(data);
}
fillArray().then(doStuff, function error(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown)
});
var arr = ["a", "b", "c"];
var response = {
"a": 1,
"b": 2,
"c": 3
};
var obj = {};
var dict = [];
function fillArray() {
return $.when(arr).then(function(phpReturnVal) {
for (var i = 0; i < phpReturnVal.length; i++) {
// return same `response` here ?
$.when(response).then(function(data) {
dict[arr[i]] = data;
});
};
return dict
});
}
function doStuff(data) {
console.log(data)
}
fillArray().then(doStuff, function error(err) {
console.log(err)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

How to pull JSON data from two different sources?

I was wondering if there is a way to pull and use JSON data from two different sources. Currently, the code looks like this:
//JSON1
$.getJSON('url1',function(data){
$.each(data,function(key,val){
//code
});
});
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
//code
});
});
When I do this, i seems that variables created from one JSON function aren't available in the other one, which makes it hard for them to be useful together.
Is there a better way to have these two work together?
This function takes an array of urls and a callback as parameters:
function getMultiJSON(urlList,callback) {
var respList = {};
var doneCount = 0;
for(var x = 0; x < urlList.length; x++) {
(function(url){
$.getJSON(url,function(data){
respList[url] = data;
doneCount++;
if(doneCount === urlList.length) {
callback(respList);
}
});
})(urlList[x]);
}
}
You would use it like this:
getMultiJSON(['url1','url2'],function(response) {
// in this case response would have 2 properties,
//
// response.url1 data for url1
// response.url2 data for url2
// continue logic here
});
You might want to add a timeout as the function will never call your handler should any of the URLs fail to load
Variable declared within the functions using var (or blocks, using let) are not available outside of the functions (or blocks).
$.getJSON('url1',function(data){
$.each(data,function(key,val){
var only_accessible_here = key;
});
});
So if you want variables that are accessible outside the scope of the function they are declared in, you need to declare them outside of the function they are used in.
var combined_stuff = ''
$.getJSON('url1',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
As Marc B says, there is no way to know which order the combined_stuff variable will be updated, either by JSON1 first, or by JSON2 first, or by only one, if one of the getJSON calls fail, or by neither if both fail.
If the order of updating is important, call the one you want to use second in the function of the one you want to call first.
var combined_stuff = ''
$.getJSON('url1',function(data){
$.each(data,function(key,val){
combined_stuff += val;
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
});
});
Easily using the open source project jinqJs (http://www.jinqJs.com)
var data1 = jinqJs().from('http://....').select();
var data2 = jinqJs().from('http://....').select();
var result = jinqJs().from(data1, data2).select();
The example does a sync call, you can do an async call by doing something like this:
var data1 = null;
jinqJs().from('http://....', function(self){ data1 = self.select(); });
Result will contain both results combined.
If you control the endpoint, you could make it return all of the data you want in one shot. Then your data would look like:
{
"url1_data": url1_json_data,
"url2_data": url2_json_data
}
If you still have 2 endpoints you need to hit, you can pass the result of your first ajax call to the second function (but this makes your 2 ajax calls synchronous):
function getJson1(){
$.getJSON('url1',function(data){
getJson2(data);
});
}
function getJson2(json1Data){
$.getJSON('url2',function(data){
//Do stuff with json1 and json2 data
});
}
getJson1();
I would recommend you to use $.when function available in jquery to execute both the methods in parallel and then take the action. See the code snipped below,
var json1 = [], json2 = [];
$.when(GetJson1(), GetJson2()).always(function () {
//this code will execute only after getjson1 and getjson2 methods are run executed
if (json1.length > 0)
{
$.each(json1,function(key,val){
//code
});
}
if (json2.length > 0)
{
$.each(json2,function(key,val){
//code
});
}
});
function GetJson1()
{
return $.ajax({
url: 'url1',
type: 'GET',
dataType: 'json',
success: function (data, textStatus, xhr) {
if (data != null) {
json1 = data;
}
},
error: function (xhr, textStatus, errorThrown) {
json1 = [];//just initialize to avoid js error
}
}
function GetJson2()
{
return $.ajax({
url: 'url2',
type: 'GET',
dataType: 'json',
success: function (data, textStatus, xhr) {
if (data != null) {
json2 = data;
}
},
error: function (xhr, textStatus, errorThrown) {
json2 = [];//just initialize to avoid js error
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
The returned data from each AJAX call are not available outside its own callback function. I'm sure there are more elegant (complex?) solutions, but a couple of simple, Occamic, solutions include global variables, or storing the received data in hidden input elements.
Within each callback function, just loop until the data from the other call is present:
function getJson1(){
$.getJSON('url1',function(data){
var d2 = '';
$('#hidden1').val(data);
while ( d2 == '' ){
//you should use a time delay here
d2 = $('#hidden2').val();
}
getJson2();
});
}
function getJson2(){
$.getJSON('url2',function(d2){
var d1 = '';
$('#hidden2').val(d2);
while ( d1 == '' ){
//you should use a time delay here
d1 = $('#hidden1').val();
}
//Do stuff with json1 and json2 data
});
}
getJson1();

Categories