Tomek Buszewski
Tomek Buszewski

Reputation: 7935

Can't pass values from constructor

I want to build a class to act as a controller in Angular. But I can't pass a value from constructor() to the methods in my class. The erros is:

TypeError: Cannot read property 'data' of undefined

Of course my desired result here is to do a console.log of this.data.

My code is as follows:

const app = angular.module('app', ['ngRoute']);

class ArtistController {
    constructor($route, $routeParams, $http) {
        let dataSrc = './data',
            artist = $routeParams.artist,
            data = dataSrc+'/'+artist+'.json';

        this.data = data;

        $http.get(data).then(this.renderArtist, this.fail);
    }

    renderArtist() {
        console.log(this.data);
    }

    fail(err) {
        console.log(err);
    }
}

ArtistController.$inject = ['$route', '$routeParams', '$http'];

app.config(($routeProvider) => {
    $routeProvider
        .when('/', {
            template: 'Nothing selected'
        })
        .when('/music/:artist', {
            controller: ArtistController,
            templateUrl: 'tpl/artist.html'
        })
        .otherwise({
            template: '404'
        });
});

What can I do?

Upvotes: 0

Views: 53

Answers (1)

Patrick Kelleter
Patrick Kelleter

Reputation: 2771

your "this" in renderArtist will not be your "this" in your constructor, because in javascript "this" is always context sensitive. you give the function renderArtist as a reference to the $http service as a callback

$http.get(data).then(this.renderArtist, this.fail);

so when $http finishes its call it will call the function renderArtist from the window-context. hence "this" will be "window". you have two options:

1) bind the callback to the context you want it to hve

 $http.get(data).then(this.renderArtist.bind(this), this.fail);

2) use the arrow notation (have a look for ES6 specs to understand why this works - in the end it does the same as the first approach "by default". it memorizes the context it was defined at

 renderArtist = () => {
        console.log(this.data);
    }

Upvotes: 2

Related Questions