JavaScript this scope in callback functions - javascript

How can I access object properties from functions which will be called as callback function. Please see code below. How can I access config property from processData function which will called when data is received from the server in ajax call.
MyClass: {
config: {
name: "",
id: ""
},
loadData: function() {
MyApi.getData(
this.config,
this.processData, //sucess
this.failureHandler //failure
);
},
processData: function() {
// how to access config object here?
}
}
Probably you can create an anonymous handler function and use call or apply to pass the this scope to actual handler function but is there a better solution than that?

Related

Function property is not a function in Polymer

I am using the Polymer framework for my project in which I'm declaring a function callback in properties and trying to call it from another function. But on accessing it I'm getting an error:
Uncaught TypeError: this.callback is not a function
Please have a look into this.
Polymer({
is: "parent-dom",
properties: {
people: {
type: String,
value: "df"
},
item: {
type: String,
value: "asdf",
notify: true
},
callback: {
type: Object,
value: function(index) {
console.log("Inside callback function");
}
},
},
showTargetColorDialog: function(e) {
this.callback("sadf");
}
});
Could you please provide more details about what you would like to achieve, since specify Polymer properties as functions it's not very common case?
So you could declare public methods on your element, like you did with showTargetColorDialog, and they will be accessible to be called like:
document.querySelector('parent-dom').showTargetColorDialog();
But again it's not very "Polymer way" to that.
To answer your original question, if you really need set callback as Polymer property (I'm still not sure why), but you could:
callback: {
type: Object,
value: function() {
return function(index) {
console.log("Inside callback function ", index);
};
}
},
And then you will be able to call this.callback('something');

Callback function on custom $resource action

I have added a custom action to a $resource:
var myResource = $resource('some/url/:someParam',
{
someParam: '#someParam'
},
{
update: {
method: 'PUT'
}
});
I am attempting to have a function run on completion. According to Angular's documentation, I'd do it in the following way:
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
Yet the following never invokes the success function even though the request is successful:
myResource.update({ someParam: 'a value' }, { myPostData: 'goes here' }, function(a,b) {
// this function never gets invoked
});
The documentation also says this:
The Resource instances and collections have these additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
But this doesn't work either:
myResource.update({ someParam: 'a value' }, { myPostData: 'goes here' }).$promise.then(function() {
// do stuff
});
Am I missing something here? Any help would be greatly appreciated.

Return a value asynchronously acquired in a function

This can be considered a general programming question or even logic question, as it's language independent.
I have the following piece of code in JavaScript:
...
{text: 'Modelo', dataIndex: 'model', filterable: true,
renderer: function(value) {
// this will asynchronously load the object "Model" from the database which have primary key equals to "value".
MyApp.model.Model.load(value, {
scope: this,
success: function(record, operation) {
// this will be executed if succeeded. I need to return the "record" parameter in the outer function.
}
});
return value; // There must be a way to return the "record" parameter from above.
}
},
...
As stated in the comments, there's the outer function renderer that calls an inner asynchronous function load that retrieves the value record I need to return from the outer function.
I tried ugly things like an empty while-loop waiting for a variable declared in the outer function to be set in the inner function and then return it, but no success, the loop ended up being infinite.
You can't return directly as the success callback fires after the return has occurred. Instead you can continue this callback pattern in your code... if you change the function signature of renderer to accept a callback:
{text: 'Modelo', dataIndex: 'model', filterable: true,
renderer: function(value, successCb) {
MyApp.model.Model.load(value, {
scope: this,
success: function(record, operation) {
if(successCb){
successCb(record, operation);
}
}
});
//return void, and communicate back to the caller using successCb above.
}
},
and the caller of renderer supplies a callback:
myObj.renderer(someVal,function(rec,op){
//do something
});
now you can get data out of your function asynchronously.

Why can I not use this.posts out side the success function?

Maybe I am not understanding scoping but in the following:
AisisWriter.Routers.Posts = Backbone.Router.extend({
writer_posts: null,
posts: null,
routes : {
'': 'index'
},
initialize: function() {
this.writer_posts = new AisisWriter.Collections.Posts();
},
index: function() {
var self = this;
this.writer_posts.fetch({
reset: true,
success: function(collection, response, options){
this.posts = collection;
console.log(this.posts);
}
});
console.log(self.posts)
}
});
inside the success: function(){} the this.posts console log has two posts in it. it looks like:
child {length: 1, models: Array[1], _byId: Object, constructor: function, model: function…}
But when I try and use this.posts out side the fetch call, it returns null. Why is that? Is this not scoped properly? or am I doing something wrong?
You are not being able to get access to your this.posts only because it is executed sooner than you get the response. You even don't have to save 'this' in the self variable. To check it just add in the initialize function this line:
this.listenTo(this.writer_posts, 'reset', this.test);
And then create test function:
test: function() { console.log(this.posts); }
As you will see collection is saved properly.
Since your fetch might take time to get into success promise the next line is getting executed sooner before that.
index: function() {
var self = this;
this.writer_posts.fetch({
reset: true,
success: function(collection, response, options){
//write your callback function inside the success
//self.afterSuccess(collection);
}
});
},
You can pass the parameters for the function and fetch it.
afterSuccess: function(collection) {
console.log("the collection has"+JSON.stringify(collection));
}

Variable passed from one function to another become undefined after .post with jQuery

I have a function successfully pass data_user_id with a value of 2 into the function getOptionsList(fieldname_validation,data_user_id) But then, I think somehow the .post statment's async nature took the value out so when I do a .post in the getOptionsList function, then the data_user_id will be undefined in function it passed next. Like this:
function getOptionsList(fieldname_validation,data_user_id){
$.post('Controller.php',
{
action: 'get_options_list',
user: userJson
},
function(data, textStatus, fieldname_validation,data_user_id) {
data_user_id=data_user_id;
showOptionsList(data, fieldname_validation,data_user_id);
$('#indicator').hide();
},
"json"
);
}
function showOptionsList(jsonData, fieldname_validation,data_user_id){
alert('showOptionsList ran!');
alert(data_user_id);//Here the same variable will alert as undefined.
}
How can I fix this issue?
You've declared data_user_id as a parameter to your inner function, so it's distinct from the parameter of the outer method. Since the $.post method will only provide 3 parameters to the callback, the fourth parameter will always be undefined (the third parameter will be a jqXhr object, which I don't believe is what you expect).
The solution is to remove this parameter (and probably fieldname_validation as well):
function getOptionsList(fieldname_validation,data_user_id){
$.post('Controller.php',
{
action: 'get_options_list',
user: userJson
},
function(data, textStatus) {
showOptionsList(data, fieldname_validation, data_user_id);
$('#indicator').hide();
},
"json"
);
}

Categories