Javascript callback not firing when using this - javascript

Hello I have this code which works fine
var app = {
callback: null,
jqmReady: null,
pgReady: null,
// Application Constructor
initialize: function(callback) {
this.callback = callback;
this.jqmReady = $.Deferred();
this.pgReady = $.Deferred();
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', app.pgReady.resolve, false);
$(document).on("pageinit", app.jqmReady.resolve);
$.when(app.jqmReady, app.pgReady).then(app.isReady);
},
isReady: function() {
app.callback();
}
};
code is being initialized like this:
app.initialize(function(){
navigator.notification.alert('Hello there!', function(){}, 'Notify', 'Ok');
});
however my isReady function was like this at first and the callback was not called:
isReady: function() {
this.callback();
}
Why is this happening ? isn't the scope of this = app inside isReady() like in the initialize() function ?
Could someone explain to me why it doesn't work with this.callback() ?

You've created an object, not a class or an instance of a class. Change your this to app throughout your initialize function. You're doing that already in your isReady and bindEvents functions. So keep that going in initialize.

Related

Vuejs calling a method from $on event

Am building a vuejs component
methods: {
filterPeople: function() {
console.log('hello')
//do some good stuff
},
},
beforeCreate() {
//do some ajax stuff
},
mounted() {
Event.$on('applied', function() {
console.log('the event is being caught')
this.filterPeople();
})
})
The error I get is
this.filterPeople(); is not a function
When I move it outside the Event.$on block it does call the method.
How does this work?
It was all to do with Scope
var self = this;
Event.$on('applied', function() {
self.filterPeople();
})
Use arrow functions to save the context:
Event.$on('applied', () => this.filterPeople());

Ember.js: this._super in a callback function

I'm trying to figure out how to use this._super when the Ember's object method is called from a callback.
I know that I could assign var _super = this._super before the callback is called but I don't like it.
I want to have the this object containing proper _super method inside the callback.
My code is here: http://emberjs.jsbin.com/hasehija/6/edit.
App.BaseMixin = Ember.Mixin.create({
init: function() {
console.log("base");
}
});
App.Utils = Ember.Object.extend({
callbackMethod: function(callback, ctx) {
// asynchronous callback
Ember.run(function() {
callback.call(ctx);
});
}
});
App.MyObject = Ember.Object.extend(App.BaseMixin, {
init: function() {
console.log("MyObject");
var _super = this._super;
App.Utils.create().callbackMethod(function() {
this._super(); // this._super is undefined here
// _super() would work
}, this);
}
});
App.ApplicationController = Ember.Controller.extend({
init: function() {
new App.MyObject();
}
});
Do you know any way to fix it?
UPDATE:
It turned out that it was fixed in Ember 1.5.0 (#GJK: thank you for the answer) and I was using Ember 1.4.0.
extend defines a class
App.Utils = Ember.Object.extend({
callbackMethod: function(callback, ctx) {
callback.call(ctx);
}
});
create builds an instance of the class
App.Utils = Ember.Object.create({
callbackMethod: function(callback, ctx) {
callback.call(ctx);
}
});
or
App.Utils.create().callbackMethod(function() {
this._super();
}, this);
http://emberjs.jsbin.com/hasehija/7/edit
Or avoid overriding init
App.ApplicationController = Ember.Controller.extend({
doSomething: function() {
new App.MyObject();
}.on('init')
});

JS scope: call parent function using namespace

How do I call a parent namespace function from within a function?
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
setTimeout ( function () {
myNamespace.funcOne(); //how do I call funcOne?
}, 2000);
}
}
The usual way would be to use the this keyword inside the literal
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
var self = this;
setTimeout ( function () {
self.funcOne();
}, 2000);
}
}
But what you're doing should work just fine as well -> FIDDLE

How to bind dynamic function to dynamic event

I have a simple jQuery function with optional parameters, All I want is to pass control name, event name and value or function name than bind it to the passed control.
jQuery Function
BindEvents: function (options) {
var defaults = {
Control: null,
Events: null
}
settings = $.extend({}, defaults, options);
if (Events != null) {
$(Control).on(Events['name'], function () {
'How to call passed function';
});
}
}
Calling the Function
$.fn.BindEvents({
Control: "#txtTest",
Events: { "name": "focus", "value": "$.fn.test()" }
});
1) You forgot to use 'settings' prefix:
BindEvents: function (options) {
// defaults do not make sense this way, but they probably have a sane default in your code, right?
var defaults = {
Control: null,
Events: null
}
settings = $.extend({}, defaults, options);
if (settings.Events != null) {
$.each(settings.Events, function(eventName, handler) {
$(settings.Control).on(eventName, handler);
});
}
}
2) call BindEvents with an function reference instead of a string. I also changed the Event object a bit:
$.fn.BindEvents({
Control: "#txtTest",
Events: { "focus": $.fn.test }
});

Setting correct this-value in requestAnimationFrame

I have an app-object constructer that looks like this:
var app = function(loadedsettings) {
return {
init: function() {
this.loop();
},
loop: function() {
this.update();
window.requestAnimationFrame(this.loop);
},
update: function() {
//loop through settings and call update on every object.
},
settings: [
//array of settings objects, all with update methods.
]
};
}
Then when I do:
var theApp = app(settings);
theApp.init();
I get:
Uncaught TypeError: Object [object global] has no method 'update'
because when requestAnimationFrame is called, the this-value inside the loop function is set to window.
Does anybody know how to call requestAnimatinFrame with the 'theApp' object set as the this-value?
You can create a bound function (with a fixed this), and pass that to requestAnimationFrame:
var app = function(loadedsettings) {
return {
init: function() {
this.loop();
},
loop: function() {
this.update();
window.requestAnimationFrame(this.loop.bind(this));
},
update: function() {
//loop through settings and call update on every object.
},
settings: [
//array of settings objects, all with update methods.
]
};
}
I think that a browser which supports requestAnimationFrame will also support Function.prototype.bind, but in case you come across one that doesn't, there are polyfills available.
You need to cache a reference to this:
var app = function(loadedsettings) {
var self = this;
return {
init: function() {
self.loop();
},
loop: function() {
self.update();
window.requestAnimationFrame(self.loop);
},
** snip **
...

Categories