How to keep context in javascript methods after call ajax? [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
hi i have a problem with es6 and in particulary the methods of class. See my exemple :
my first class :
class A{
constructor(){
this.B = new B();
this.test = 5;
}
methodA1(){
B.methodB1(this.methodA2);
}
methodA2(){
console.log(this.test);
}
}
the second class :
class B{
methodB1(callback){
$.get("url",function(data){
...
callback();
});
}
}
When you execute methodA1, the code return : this is undefined (in a methodeA2) !
In fact when you call a callback function in ajax call the callback lost the context of class. Somebody have an idea to skirt this problem ?
Thanks.

You can use .bind to bind this.
methodA1(){
this.B.methodB1(this.methodA2.bind(this));
}

You get an error because you are not correctly referencing the B property you created in your constructor.
If you are sure that you'll be invoking methodA1 in the context of class A, then you can refer to property B by this.B. The this conext would point to the reference of the class A where B exists:
class A{
constructor(){
this.B = new B();
this.test = 5;
this.methodA2 = this.methodA2.bind(this);
// I prefer to bind my methods in the constructor so they are bound once
}
methodA1(){
this.B.methodB1(this.methodA2);
// ^ -- the B property created in constructor B exists as a property
// of this class, to reference it within a class method you need
// to call this.B
}
methodA2(){
console.log(this.test);
}
}
class B{
methodB1(callback){
$.get("url",function(data){
...
callback();
});
}
}
const a = new A();
a.methodA1(); // will log out 5 when the `$.get` request has its callback invoked

Related

How to call a function which is inside another function in JavaScript [duplicate]

This question already has answers here:
Calling a Function defined inside another function in Javascript
(11 answers)
Closed 2 years ago.
function a(){
this.i = 10,
function b(){
console.log("Regular function ",this.i, this)
}
}
Here I want to call function b
Because of the use of this within the function, you need to call the a function as a "constructor function" (with the new keyword) or invoke it with call(), apply(), or bind() so that you can specify context for this.
And, because the b function uses the context of a, it should be either returned from the parent or declared as an instance method of a with this.b = function()...
function a() {
this.i = 10;
// To make the nested function have access to the
// parent function's instance data, you can either
// return it from the parent or declare it as an
// instance method of the parent (shown here):
this.b = function(){
console.log("Regular function ", this.i, this);
}
}
// Invoke a as a constructor function
let newA = new a();
// Now call b within the context of a
newA.b();
You need to return the function first as shown below:
function a(){
this.i = 10;
return function b(){
console.log("Regular function ",this.i, this)
}
}
And then call it using:
a()()
UPDATE: this keyword in the above example will point to the global scope. To make sure we use this within the function context we can use call() method on function a() and pass the object to which this will associate it's scope.
function a(){
this.i = 10;
return b = ()=>{
console.log("Regular function ",this.i,this)
}
}
a.call({i:10})();
Note: I have also used arrow method for function b() to keep this scope used within it as its function a()'s scope.

Access parent class variable from method, used by another class [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I have two classes which are not related:
class A {
myVar = null;
myFunc() {
console.log(this.myVar)
}
}
class B {
constructor(func){
this.func = func;
}
callFunc() {
this.func();
}
}
My problem is the following:
let a = new A();
let b = new B(a.myFunc);
b.callFunc();
This will be undefined because this in console.log(this.myVar) won't refer to the instance of class A, but the instance of class B. How can I access the global variable of class A when calling the function from another class?
You could use a.myFunc.bind(a), specifying that you want myFunc's this to refer to the a instance.
The bind() method creates a new function that, when called, has its this keyword set to the provided value
Also, don't forget your new operators :)
class A {
myVar = "Hello world";
myFunc() { console.log(this.myVar) }
}
class B {
constructor(func){ this.func = func; }
callFunc() { this.func(); }
}
let a = new A();
let b = new B(a.myFunc.bind(a));
b.callFunc();

Calling class function from callback function calls in nodejs [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I have this situation
class A {
a(params) {
//some code here
}
b(params) {
//some code here
}
c(params) {
this.a(function(data) {
console.log(this); // undefined
this.b(); // error no function b of undefined
})
}
}
I have tried binding this to 'a' using bind(this) but it says Cannot read property 'bind' of undefined or this is not defined. When I print this, I get class A. I want to call it inside 'a' function.
When you have defined a new function, the meaning of this has been changed inside it. You either need to use an arrow function:
this.a((data) => {
console.log(this); // class A
this.b();
})
or save the reference of this in a local variable:
var self = this;
this.a(function(data){
console.log(self); // class A
self.b();
})
Not sure at which point you are expecting the "b" method execution. I've added jsFiddle here: https://jsfiddle.net/k3jkobae/ and just saw that there was short correct answer while I was wrapping mine :) The arrow function is best suited.
class A {
a( callback ){
console.log('a');
callback();
}
b(params){
console.log('b');
}
c(params) {
this.a( () => this.b() );
}
}
const myClass = new A();
myClass.c();

How to circumvent the ES6 Class scoping issue with 'this' key word [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
How do I write a named arrow function in ES2015?
(8 answers)
Closed 7 years ago.
For example in the Class constructor:
Socket.on('user:join', onUserJoin);
'onUserJoin' is declared as a method of the class but is being called by socket.io so the 'this' is not my Class. A way to resolve this is to use the '=>' function.
example:
Socket.on('user:join', (data)=>{
this.isOnline = true;
});
Now 'this' is my class, but how do I reference this anonymous function to unsubscribe ?
socket.removeListener('user:join', ????);
I did try this:
let self;
class RoomController {
constructor() {
self = this;
}
...
}
and reference the self in the methods but the self was being shared across sockets...
naming the anonymous function could solve it but I preferred for my case the bind option.
You can use Function.prototype.bind.
Socket.on('user:join', onUserJoin.bind(this));
This ensures that onUserJoin has the correct context, which will be the instance of your class.
You can always bind the arrow functions to the names.
For example,
class RoomController {
constructor() {
this.flag = true;
}
// Assign the arrow function to the name `setFlag`
setFlag = (v) => this.flag = v;
}
let r = new RoomController();
function tester(func) {
func(false);
console.log(r.flag);
// false
func(true);
console.log(r.flag);
// true
}
// Now you can pass the function around, `this` will still refer the object `r`
tester(r.setFlag);

How to access class variables from inner prototype - javascript [duplicate]

This question already has answers here:
'this' in function inside prototype function [duplicate]
(8 answers)
Closed 7 years ago.
I might not be clear with my title of the question. Sorry for that.
Here is what I wanted to do.
I'm trying to use prototyping pattern in javascript. I created a class as following.
var MyClass = null;
(function() {
MyClass = function() {
this.clsVar = "I'm inside constructor";
};
MyClass.prototype = {
constructor: MyClass,
myFunc1: function() {
console.log("I'm func1 accessing constructor variable : " + this.clsVar);
},
nested: {
myFunc2: function() {
console.log("I'm func2 accessing constructor variable : " + this.clsVar); // I know, this will never point to the class scope
}
}
}
}())
I'm creating an object.
var my = new MyClass();
my.myFunc1(); // which prints "I'm func1 accessing constructor variable : I'm inside constructor"
my.nested.myFunc1(); // as expected, it prints "I'm func2 accessing constructor variable : undefined
All I am trying to do is, I should be able to access clsVar from nested.myFunc2
is that possible.? Any help is greatly appreciated and needed.
Thanks.
Actually, there is a point.
The this inside your myFunc2 does not refer anymore to MyClass but to another context. So, the fastest way is to do is to use call or apply like:
var myNewObject = new MyClass();
myNewObject.nested.myFunc2.call(myNewObject, arg1, arg2);
or
myNewObject.nested.myFunc2.apply(myNewObject, [arg1, arg2]);
JavaScript's prototype-based class system does not allow this.
MyClass's prototype will be shared between all instances of the class. In the following code, both instances will use the same function instance...
var first = new MyClass(), second = new MyClass();
first.nested.myFunc2(); <-- Same prototype function
seecond.nested.myFunc2(); <-- Same prototype function
When the code enters the "myFunc2" definition, which parent should it be accessing?
If you need access to the parent's "this" value, you'll have to use a closure and set up the nested object in the parent constructor as below.
var MyClass = null;
(function() {
MyClass = function() {
this.clsVar = "I'm inside constructor";
var that = this;
this.nested = {
myFunc2: function() {
console.log("I'm func2 accessing constructor variable : " + that.clsVar); // I know, this will never point to the class scope
}
}
};
MyClass.prototype = {
constructor: MyClass,
myFunc1: function() {
console.log("I'm func1 accessing constructor variable : " + this.clsVar);
}
}
}())

Categories