Jcr Jcr - 5 months ago 16
AngularJS Question

Update $scope inside .then?

I have a function inside a controller and I'm confused as to how to update a $scope variable from inside a .then function.

Heres my function:

searchSpotify(query, $scope) {
this.Spotify.search(query,'track').then(function (data) {
console.log(data.tracks.items); // this is working
$scope.result = data;
});
}


In the console log I receive this error:

TypeError: Cannot set property 'result' of undefined


Do I use $scope.$apply somehow?

EDIT:

Here's the entire controller for context

(function() {

class SelectionController {
constructor(User, groupService, selectionService, songService, $scope, $routeParams, Spotify) {
this.groupId = $routeParams.groupId;
this.selectionId = $routeParams.selectionId;
this.groupService = groupService;
this.selectionService = selectionService
//this.selections = this.selectionService.getSelections();
this.songService = songService;
this.searchResults;
this.$scope = $scope;
this.Spotify = Spotify
}

searchSpotify(query) {
this.Spotify.search(query, 'track').then(function(data) {
console.log(data.tracks.items);
$scope.result = data;
});
}

addSong(name, artist, album) {
alert('called from selection controller');
this.songService.addSong(this.selectionId, name, artist, album);
}

createSelection(name, description) {
this.selectionService.createSelection(this.groupId, name, description);
}

deleteSelection(selection) {
this.selectionService.deleteSelection(selection);
}
}

angular.module('songSelectionApp')
.controller('SelectionController', SelectionController);

})();

Answer

Save reference to $scope:

    searchSpotify(query) {
        var $scope = this.$scope;
        this.Spotify.search(query, 'track').then(function(data) {
            console.log(data.tracks.items);
            $scope.result = data;
        });
    }

Or use arrow functions:

    searchSpotify(query) {
        this.Spotify.search(query, 'track').then((data) => {
            console.log(data.tracks.items);
            this.$scope.result = data;
        });
    }

.bind(this) should also work, as another answers suggest.

Regarding $scope.$apply: you need it only when you want to change a $scope outside of a $digest, for example when you use external (non-angular) libraries/functions, like WebSocket, or jquery event listeners. Untill Spotify is an angular service/factory - you don't need $scope.$apply

From docs:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).

Comments