Reputation: 7935
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
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