Access to the widget instance using 'this'

283
7
Jump to solution
11-22-2017 02:09 PM
Alexys_HerleymRodriguez_Avell1
New Contributor II

I am trying to configure a personalized widget for ArcGis Javascript Api 4.5.

My issue is related to the use of 'this' (a MapView) inside of method on() of esri/views/View

I used this.view.on inside a private method of my widget named onViewChange(). I attached all the TypeScript code.

It looks like this:

@property()
@renderable()
view: MapView;

....

private _onViewChange() {
      
this.view.on('pointer-up', function(response){
      this.centroanteriorgeoX = this.state.longitudanterior,   \\Here 'this' is undefined
      this.centroanteriorgeo = {
         x: this.state.longitudanterior,
         y: this.state.latitudanterior,
      };
});

this.centroanteriorpla = {  \\Here this works fine!!
      x: this.state.xanterior,
      y: this.state.yanterior,
};
...
};

I have access to 'this' inside the private onViewChange method but outside this.view.on

access to this is ok

I can't use 'this' inside of this.view.on because it is undefined.

How can I use and change properties of 'this' (MapView) inside Mapview.on, inside a private method, inside a new widget class that extends Accessor?

this is undefined

I tryed to do the same inside this.view.watch, but I have the same problem.

Cheers!!

Alexys 

0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor

Since you are already using TypeScript, you want to use fat arrow functions, which will inherit the scope of the block that it's in.

this.view.on('pointer-up', (response) => {
      this.centroanteriorgeoX = this.state.longitudanterior,   \\should work now
      this.centroanteriorgeo = {
         x: this.state.longitudanterior,
         y: this.state.latitudanterior,
      };
});

You can read more about it here.

An Introduction to JavaScript ES6 Arrow Functions - Node.js @ IBM 

View solution in original post

7 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Add the dojo/_base/lang library in your require array and then use lang.hitch(this, _onViewChange); to maintain the scope of this keyword.

Alexys_HerleymRodriguez_Avell1
New Contributor II

Cheers Robert for your very fast answer!

Now, I have this module problem.

Visual Studio Code said "Cannot find module 'dojo/_base/lang'

import lang = require("dojo/_base/lang");

I configured my widget folder with:

npm init --yes
npm install --save @types/arcgis-js-api
npm install dojo-typings --save-dev
Create tsconfig.json

Inside onViewchange() I wrotte: 

lang.hitch(this, this._onViewChange);

Do I need to put it inside the constructor?

Regards!

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Sorry I am not a npm node guy so I can’t help with that but it will take care of your scope issue when you get it installed correctly.

Alexys_HerleymRodriguez_Avell1
New Contributor II

Hi Robert, 

I just review this [TypeScript - Setting up your development environment for Javascript Api 4.5] and [how to guide on how to develop with Dojo 1 in TypeScript using dojo/typings] and I realized that I just needed to change my tsconfig.json to:

{
    "compilerOptions": {
        "module": "amd",
        "noImplicitAny": true,
        "sourceMap": true,
        "jsx": "react",
        "jsxFactory": "tsx",
        "target": "es5",
        "experimentalDecorators": true,
        "preserveConstEnums": true,
        "suppressImplicitAnyIndexErrors": true
    },
    "include": [
        "./app/*"
    ],
    "exclude": [
        "node_modules"
    ]
}

Thank you very much for your help

0 Kudos
Alexys_HerleymRodriguez_Avell1
New Contributor II

Hi Robert,

Inside _onViewhange and before this.view.on('pointer-up', ...}); I wrote

lang.hitch(this, this._onViewChange);

I also used the same sentence inside the constructor.

But I don't have access to 'this' inside this.view.on.

__________________________

I fixed it using var that = this;

I wrote

var that = this;

just before

this.view.on('pointer-up', function(response){
    that.centroanteriorgeo.x = that.state.longitudanterior,
    that.centroanteriorgeo = {
        x: that.state.longitudanterior,
       y: that.state.latitudanterior,
    };
});

And now I have access to 'this' inside this.view.on, inside _onViewChange

Thank you very much for your help!

0 Kudos
ReneRubalcava
Frequent Contributor

Since you are already using TypeScript, you want to use fat arrow functions, which will inherit the scope of the block that it's in.

this.view.on('pointer-up', (response) => {
      this.centroanteriorgeoX = this.state.longitudanterior,   \\should work now
      this.centroanteriorgeo = {
         x: this.state.longitudanterior,
         y: this.state.latitudanterior,
      };
});

You can read more about it here.

An Introduction to JavaScript ES6 Arrow Functions - Node.js @ IBM 

View solution in original post

Alexys_HerleymRodriguez_Avell1
New Contributor II

Hi Rene, According to your advice (An Introduction to JavaScript ES6 Arrow Functions - Node.js @ IBM)

I wrote

var that = this;

just before

this.view.on('pointer-up', function(response){
    that.centroanteriorgeo.x = that.state.longitudanterior,
    that.centroanteriorgeo = {
        x: that.state.longitudanterior,
       y: that.state.latitudanterior,
    };
});

And now I have access to 'this' inside this.view.on, inside _onViewChange. It is the solution!

It does not work with var self = this;, because inside 'self' there is another object!

I was trying to use fat arrow, but I don't know how to code it. Could you please tell me how?

Thank you very much!

0 Kudos