I know that javascript does not use Class, at least not in common sense`. I will like to know how to return and save an AJAX return value in a class variable rather than calling multiple methods within the callback.
var Reader = function(){
//Initialize some variables
this.data = null;
}
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
Reader.prototype.searchData = function(param){
//Needs access to this.data
}
Reader.prototype.findData = function(id){
//Needs access to this.data
}
Reader.prototype.deleteItem = function(id){
// Needs access to this.data
}
In the above code, whatever function that needs access to the data property needs to be called within the ajax success callback, so If I have ten methods that need data, I will have to line all of them up within the callback, which I do not feel is right. How do I minimise the number of functions in the callback and ensure in some other ways that the function is successful and data is saved the instance variable data.
The essensential part is how to handle asyncronous data with JavaScript. There are some well tested solutions to this: functions and promises.
In both cass the Reader should have a constructor which assigns the data like this:
function Reader(data) {
this.data = data;
}
The callback approach requires a factory function, which has a callback.
function getReader(url, callBack) {
Ajax.success(function(data){
callBack( new Reader(data) );
});
}
And use it like
getReader(url, function(reader) {
reader.searchData();
});
The Promise -approach does not require immediately a callback so the result can be stored in a variable and passed around as a variable which has some advantages:
function getReaderPromise(url) {
return new Promise( function( resolve, reject ) {
Ajax.success(function(data){
resolve( new Reader(data) );
});
});
}
However, using the promise usually requires calling the then function of the promise:
getReaderPromise(url).then( function(reader) {
reader.searchData();
});
// Fat arrow syntax
getReaderPromise(url).then( (reader) => {
reader.searchData();
});
In the future you can get rid of the callbacks with Promises using ES6 generators with yield like
let reader = yield getReaderPromise( url );
As explained in here: https://davidwalsh.name/async-generators
You could try something like:
var Reader = function(){
//Initialize some variables
this.data = null;
}
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
this.data = Ajax({url: urlPath}); // return promise
}
Reader.prototype.searchData = function(param){
//Needs access to this.data
if(this.data){
this.data.then(...);
}
}
Reader.prototype.findData = function(id){
//Needs access to this.data
if(this.data){
this.data.then(...);
}
}
Reader.prototype.deleteItem = function(id){
// Needs access to this.data
if(this.data){
this.data.then(...);
}
}
In your code:
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
"this" is not the Reader instance context, you should change it to
Reader.prototype.makeAjaxCall = function(urlPath){
var myThis = this;
//Make and Ajax call and return some value
Ajax.success(function(data){
myThis .data = data;
});
}
To keep the pointer to Reader instance in myThis variable and access inside the success function