use a function to store each ajax call data - javascript

I want to store data between ajax calls, so that I can have my accumulated data in an object.
I can get the data of each of the calls, but I am not able to accumulate the data in one whole array.
I created the dataAccumulator () function, so that when I call accumData.append the data for a single call can be pushed to the holder array.
I keep getting the error Cannot read property 'append' of undefined or Uncaught TypeError: dataAccumulator is not a function no matter where I declare or call the function...
This is the code:
var inter;
var dataAccumulator = dataAccumulator(); //object of interest
function startTempMonit()
{
$(document).ready(function()
{
time= 0;
inter = setInterval(function()
{
$.ajax // ajax call starts
({
//not relevant for the question. arguments removed...
})
.done(function(data) {
//problem here. data is foreach call.
//I would like to accumulate each of the data to handle the whole here.
dataAccumulator.append(data);
});
time= time + 0.5;
}, 500)
});
};
function dataAccumulator () {
let accumData = [];
console.log("accumData function created")
function append(data) {
accumData.push(data);
console.log(accumData); //log the accumulated data each time
}
this.append = append;
};
I guess my problem is with js scopes. I want to keep my accumData array available inside the ajax call .done. That is the summary of my problem.

The first step is always to get rid of global variables. The second step is to use events instead of global state.
Register a callback that is called every time data has arrived. Then work with the data in the callback.
function startTempMonit(callback) {
var time = 0;
return setInterval(function () {
$.ajax({
url: '....',
data: '.....' + tiempo
dataType: '.....',
})
.done(function (data) {
console.log("received", data);
callback(data);
});
time += 0.5;
}, 500);
}
$(function () {
var inter, accumData = [];
$("#buttonStart").click(function () {
inter = startTempMonit(function (data) {
accumData.push(data);
// do something, i.e. add it to a table or a chart
});
});
$("#buttonStop").click(function () {
clearInterval(inter);
});
});

Related

function reading JSON data not passing to variables

I am creating a function to read different JSON files. The problem is when I try to pass the array.
I keep getting 'undefined' once I am back to my primary function.
Reading the file works but when I try to use the variable I get 'undefined'.
I could use some help. thanks.
This is the file I read 'data.json':
[
{
"code":"10000",
"name":"new",
"filter":"Office",
"label":"NEW"
},
{
"code":"10001",
"name":"classic",
"filter":"Office",
"label":"CLASSIC"
},
{
"code":"10002",
"name":"old",
"filter":"Office",
"label":"OLD"
}
]
Here's my code:
function readfile(myfile) {
var mydata;
$.get(myfile, function (data) {
mydata = JSON.parse(data);
console.log(mydata); // result ok
});
console.log(mydata); // undefined
return (mydata); // return 'undefined'
}
var content = readfile('data.json'); //should be an array
console.log(content); // undefined
You're almost there!
The jQuery $.get() method is an asynchronous call. That means that instead of making the request to get myfile, waiting until it is complete, and then continuing from there, the code will make the request and continue on while the request is done in the background.
There are two things you can do here.
The first thing you can do is simply move your logic inside the callback function like so
$.get(myfile, function (data) {
mydata = JSON.parse(data);
console.log(mydata); // do whatever you need
});
However, if you want to continue using the readfile method, you can make the $.get request synchronous, wait for the response, then return from it.
Like so:
function readfile(myfile) {
var mydata;
$.get({
url: myfile,
async: false,
success: function(data) {
mydata = data;
}
});
return mydata;
}
Get is asynchronous meaning that it will not execute in the order it is written.
$.get(myfile, function (data) {
mydata = JSON.parse(data);
console.log(mydata); // result ok
});
This is why
console.log(mydata); // undefined
return (mydata);
is undefined, because the values are not actually set from get().

jquery get data from php page after every 2 secounds

I am get data from php page after every 2 secounds the data is very large when i call it once then the data comes but when i place my code in setinterval function then the data in console is not showing I place this code in setinterval function because after every 2 sec i need fresh data any idea plz share
var data_array = '';
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
},
error:function(errorMsg)
{
}
});
}, 5000);
console.log(data_array);
There's a couple of issues you have here, the main one being that you're trying to make a synchronous ajax call, and that's been deprecated. You need to handle it being an asynchronous call instead...
Put the code that you want to run every time you get new data into a function and call that function in the success callback
var data_array = ''; // this is a global variable
function getNewData() {
$.ajax({
url: "./phponline.php",
})
.done(function(res) {
data_array = res; // the global variable is updated here and accessible elsewhere
getNewDataSuccess();
})
.fail(function() {
// handle errors here
})
.always(function() {
// we've completed the call and updated the global variable, so set a timeout to make the call again
setTimeout(getNewData, 2000);
});
}
function getNewDataSuccess() {
console.log(data_array);
}
getNewData();
As I explained in the comments, using setInterval with an ajax call is a bad idea as you could end up overlapping calls if they take longer than the interval. This method makes a call, waits for the result and then uses setTimeout to make the next call instead. This way you can never make an ajax call until 2 seconds after the last one was completed.
As Muhammed Atif said in the comments, you need to place the console log inside the SetInterval function.
var data_array = '';
function handleData() {
console.log(data_array);
}
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
handleData();
},
error:function(errorMsg)
{
}
});
}, 5000);
you need to call some custom function inside ajax success of setInterval to provide the effect of response stored in data_array:
var data_array = '';
$(document).on('ready', function(event, data) {
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
updateWithData();
},
error:function(errorMsg)
{
}
});
}, 5000);
updateWithData();
});
function updateWithData(){
//use data_array to make changes on each call.
}
Your console.log should be called in the success callback or directly after the ajax call in the setInterval callback.
If you place the console.log after the setInterval, data_array will be empty because it's setted 5 seconds later.
var data_array = '';
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
console.log(data_array);
},
error:function(errorMsg)
{
}
});
}, 5000);

Function Keep Triggering Before JSON Done Processing

Function 1: Get JSON Data & Store
I am creating a script where an array of twitch channels will go through the JSON function loop to be processed and then stored using "localStorage.setItem" as temporary storage. I'm saving them in name,viewer and url.
Function 2: Sort Data
Stored data can later be used to display the information without having to use function 1 again.
Problem
The sortdata function keeps on firing before function 1 is complete. Resorting in error because the data is undefined. This error popped before the console displays all the information stored from function 1.
My code:
$(window).load(function(){
$.when(getData()).promise().done(function(){
getStoredObj();
});
});
function getData(){
var streamArray=[];
jQuery.each (channels, function (i, channel) {
channelId = channel.id;
channelUrl = channel.url;
var promise = $.ajax({
dataType: "jsonp",
url: twitchApi + channelId,
success: 1,
}).done(function ( data ) {
if (data.stream == null) {
} else {
var displayName = data.stream.channel.display_name;
var viewerCount = data.stream.viewers;
streamArray.push({name: displayName, views: viewerCount, url: channelUrl});
localStorage.setItem("storedStreamArray", JSON.stringify(streamArray));
console.log(JSON.stringify(streamArray));
}
});
});
}
function getStoredObj () {
var retrievedObject = localStorage.getItem('storedStreamArray');
var parsedObject = JSON.parse(retrievedObject);
<sorting codes here>
}
Some help here really appreciated. :)
You're calling $.when with the result of getData, but getData doesn't return anything, let alone a deferred that when can use. As a result, there's nothing to wait for and your done callback calls getStoredObj immediately.
In getData, you need to collect all the deferreds returned by your ajax calls and pass them back to the caller. That would look like:
function getData(){
return jQuery.map (channels, function (i, channel) {
return $.ajax(...).done(function ( data ) {
// Do work
});
});
}
Each iteration returns its ajax deferred, which are aggregated by map and returned to the caller. Then you can run when on the result and wait for loading to finish before you sort anything.

Javascript esriRequest (dojo) in a function async issue

I am facing the following synchronization issue. I wouldn't be surprised if it has a simple solution/workaround. The BuildMenu() function is called from another block of code and it calls the CreateMenuData() which makes a request to a service which return some data. The problem is that since it is an async call to the service when the data variable is being used it is undefined. I have provided the js log that also shows my point.
BuildMenu: function () {
console.log("before call");
var data=this.CreateMenuData();
console.log("after call");
//Doing more stuff with data that fail.
}
CreateMenuData: function () {
console.log("func starts");
data = [];
dojo.forEach(config.layerlist, function (collection, colindex) {
var layersRequest = esriRequest({
url: collection.url,
handleAs: "json",
});
layersRequest.then(
function (response) {
dojo.forEach(response.records, function (value, key) {
console.log(key);
data.push(key);
});
}, function (error) {
});
});
console.log("func ends");
return data;
}
Console log writes:
before call
func starts
func ends
after call
0
1
2
3
4
FYI: using anything "dojo." is deprecated. Make sure you are pulling all the modules you need in "require".
Ken has pointed you the right direction, go through the link and get familiarized with the asynchronous requests.
However, I'd like to point out that you are not handling only one async request, but potentionally there might be more of them of which you are trying to fill the "data" with. To make sure you handle the results only when all of the requests are finished, you should use "dojo/promise/all".
CreateMenuData: function (callback) {
console.log("func starts");
requests = [];
data = [];
var scope = this;
require(["dojo/_base/lang", "dojo/base/array", "dojo/promise/all"], function(lang, array, all){
array.forEach(config.layerlist, function (collection, colindex) {
var promise = esriRequest({
url: collection.url,
handleAs: "json",
});
requests.push(promise);
});
// Now use the dojo/promise/all object
all(requests).then(function(responses){
// Check for all the responses and add whatever you need to the data object.
...
// once it's all done, apply the callback. watch the scope!
if (typeof callback == "function")
callback.apply(scope, data);
});
});
}
so now you have that method ready, call it
BuildMenu: function () {
console.log("before call");
var dataCallback = function(data){
// do whatever you need to do with the data or call other function that handles them.
}
this.CreateMenuData(dataCallback);
}

How to convert callback sample to deferred object?

I have a function that accepts a callback function where I pass the data back in. Can this converted to a deferred object for better practice?
Here is what I got:
var chapters;
var getChapters = function (fnLoad) {
//CACHE DATA IF APPLICABLE
if (!chapters) {
//CALL JSON DATA VIA AJAX
$.getJSON('/chapters.txt')
.done(function (json) {
//STORE DATA IN LOCAL STORAGE
chapters = Lawnchair(function () {
this.save(json, function (data) {
//CALL CALLBACK ON DATA
fnLoad(data);
});
});
});
} else {
//RETURN ALREADY CREATED LOCAL STORAGE
chapters.all(function (data) {
//CALL CALLBACK ON DATA
fnLoad(data);
});
}
};
Then I simply use it like this:
this.getChapters(function (data) {
console.log(data);
});
How can I use it like a promise though while maintaining the cache approach?
this.getChapters().done(function (data) {
console.log(data);
});
var chapters;
var getChapters = function (fnLoad) {
var d = new $.Deferred();
//CACHE DATA IF APPLICABLE
if (!chapters) {
//CALL JSON DATA VIA AJAX
$.getJSON('/chapters.txt')
.done(function (json) {
//STORE DATA IN LOCAL STORAGE
chapters = Lawnchair(function () {
this.save(json, function (data) {
//CALL CALLBACK ON DATA
d.resolve(data);
});
});
})
.fail(function() { d.reject(); });
} else {
//RETURN ALREADY CREATED LOCAL STORAGE
chapters.all(function (data) {
//CALL CALLBACK ON DATA
d.resolve(data);
});
}
return d.promise();
};
Relevant example
I see you have already accepted an answer, however if you take a large mental leap and store a promise of chapters instead of the chapters themselves, then the code will simplify significantly.
These days, this is probably the more generally adopted approach for a "fetch/cache" situation.
var chapters_promise;
var getChapters = function () {
//Cache data if applicable and return promise of data
if (!chapters_promise)
chapters_promise = $.getJSON('/chapters.txt').then(Lawnchair).then(this.save);
return chapters_promise;
};
What is actually promised (the chapters) will be determined by the value(s) returned by the functions Lawnchair and this.save, so you still have some work to do.
getChapters() will always return a promise, regardless of whether the data needs to be fetched or is already cached. Therefore, getChapters() can only be used with promise methods .then(), .done(), .fail() or .always(), for example :
getChapters().then(fnLoad);
You have no other way to access the chapters but that is reasonable since at any call of getChapters(), you don't know whether it will follow the $.getJSON() branch or the simple return branch, both of which return an identical promise.

Categories

Resources