0

I'm attempting to pre-populate a select list with data from a JSON file.

Controller

this.langs = [];
var promise = $lcidFactory.getLCIDS();
promise.then(
    function(payload){
        this.langs = payload.data;
        console.log(payload.data);
    },
    function(error){
        alert("[Error] "+error);
    }
);

When I review the console with the inspector the data appears. However, the following code produces an empty JSON, {}.

HTML

<template-editor-form model="cpCtrl.data">
    ...
    <pre>{{ cpCtrl.langs | json }}</pre>
    ...
</template-editor-form>

If I set this.langs = [] in line 1 of the controller to this.langs = ["one"] the template reflects the changes properly, as ["langs": ["one"]]

EDIT This question is similar to How does the "this" keyword work?, however this question addresses one of the common pitfalls of the usage of this in the context of AngularJS, in a concise fashion.

Community
  • 1
  • 1
Glenn Dayton
  • 1,345
  • 2
  • 17
  • 36
  • 2
    Possible duplicate of [How does the "this" keyword work?](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Grundy Jul 18 '16 at 15:03

5 Answers5

4

Well, i guess your problem is that "this" in your function is not the same "this" outside the function. You could set the "outside this" to a variable, so you can use that variable to access your langs even in the callback function.

var self = this;
this.langs = [];
var promise = $lcidFactory.getLCIDS();
promise.then(
    function(payload){
        self.langs = payload.data;
        console.log(payload.data);
    },
    function(error){
        alert("[Error] "+error);
    }
);
Daniel Z.
  • 1,870
  • 1
  • 15
  • 23
3

Another solution can be binding the context to the function which propvides bounded function.

this.langs = [];
var promise = $lcidFactory.getLCIDS();
promise.then(
    function(payload){
        this.langs = payload.data;
        console.log(payload.data);
    }.bind(this), 
    function(error){
        alert("[Error] "+error);
    }
);
Hamlet Hakobyan
  • 31,621
  • 6
  • 49
  • 65
2

this is window in loose mode or undefined in strict mode within callback functions. This can be fixed by

using ES5 bind (angular.bind may be used instead for legacy browsers)

promise.then(
    function(payload){
        this.langs = payload.data;
    }.bind(this),
    ...

using ES6 arrow function

promise.then(
    (payload) => {
        this.langs = payload.data;
    },
    ...

assigning this to another variable in parent function scope

var _this = this;

promise.then(
    function(payload){
        _this.langs = payload.data;
    },
    ...
Estus Flask
  • 150,909
  • 47
  • 291
  • 441
0

You should store the outer this in a variable like var that = this, and inside of resolve handler use that.langs = payload.data.

Hope it helps !

Rathma
  • 1,026
  • 1
  • 24
  • 57
0

The this in javascript is a bit odd (or different from other language) and scope related, i suggest https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

for your code:

this.langs = [];

var base = this;

var promise = $lcidFactory.getLCIDS();
promise.then(
    function(payload){
        base.langs = payload.data;
        console.log(payload.data);
    },
    function(error){
        alert("[Error] "+error);
    }
);
hayatoShingu
  • 410
  • 5
  • 11