Reputation: 445
I'm using the Soundcloud API to fetch tracks for a query typed into a searchbox like so:
$scope.tracks = [];
$scope.updateResults=function(song){
if(song.length==0){
$scope.tracks = [];
}
if(song.length>3){
SC.get('/tracks', { q: song, license: 'cc-by-sa' }, function(tracks) {
$scope.tracks = tracks;
//$scope.$apply() doesn't work either
});
}
}
$scope.updateResults
is called whenever something is typed into the searchbar. This all works fine. I've even tried logging $scope.tracks
, which is an array, and it is populated with the tracks matching the search result. According to the Soundcloud API reference, each track has a title
property. I tested this by doing:
console.log($scope.tracks[0].title)
, and I got a nice string with the title.
Now in my ng-repeat
, which is written like so:
<ul>
<li ng-repeat="track in tracks">{{track.title}}</li>
</ul>
I get several bullet points but they are all empty. In other words {{track.title}}
doesn't exist? I've tested that this is a valid property. Additionally, I know that $scope.tracks
is being populated because there are indeed list items, but they are all empty.
Thanks for any help!
EDIT: I did some research on ng-repeat
and learned that it watches for updates such as .push()
... should still not explain this weird behavior, but it might help identify the problem.
Upvotes: 1
Views: 295
Reputation: 371
This isn't going to be the most technical explanation of what's going on, so I appreciate all edits. Since the Soundcloud Javascript SDK doesn't use $http to get the tracks, the scope doesn't know it needs to update when SC.get returns the tracks. In other words, even though $scope.tracks is populated, it doesn't know to update the view. I would recommend writing a service that handles all GET/POST/PUT/DELETE requests to Soundcloud. Here is a simple example using callbacks:
.factory('Soundcloud', function($http, $rootScope, $timeout, $q) {
var request = function(method, path, params, callback) {
params.client_id = sc.soundcloud.client_id;
params.oauth_token = sc.soundcloud.access_token;
$http({
method: method,
url: sc.soundcloud.api.host + path,
params: params
})
.success(callback);
};
return {
get: function(path, params, callback) {
request('GET', path, params, callback);
},
put: function(path, params, callback) {
request('PUT', path, params, callback);
},
post: function(path, params, callback) {
request('POST', path, params, callback);
},
delete: function(path, params, callback) {
request('DELETE', path, params, callback);
}
};
})
Once you inject the service into your controller, you get tracks like this:
Soundcloud.get('/tracks', {limit: 5}, function(tracks) {
$scope.tracks = tracks;
});
Just set up where the service gets your client_id and oauth_token. Then the path is whatever endpoint you want and params is whatever parameters you want to pass to SC.
Upvotes: 1