Reputation: 87
I am struggling with this for a while, and can't figure it out. What I have is main controller, factory, and service, and I'm trying to store array from service to $scope in controller. On view on item click this function in controller is triggered:
$scope.getSongsInPlaylist = function()
{
var playlistId = this.item.idPlayliste;
$scope.Mp3Files = songInPlaylistFactory.getSongsForPlaylist(playlistId);
}
That works ok, this function retrieves item from view and sends id of that item to function in service. Than in my service I have code like this:
var Songs = [ ];
this.getSongsForPlaylist = function (id)
{
for (var i = 0; i < SongIsOnPlaylist.length; i++)
{
if(SongIsOnPlaylist[i].idPlayliste == id)
{
dataFactory.getDataById(mp3fileUrl, SongIsOnPlaylist[i].idPjesme)
.success(function (data) {
Songs.push(data);
alert(Songs[0].naslovPjesme);//Alert one
});
}
}
alert(Songs[0]);// Alert two
return Songs;
}
dataFactory is my factory that communicates with api in backend, and that works too. var Songs is defined as: var Songs = [ ]; And SongIsOnPlaylist is filled with data.
When I trigger this, alert two gives me undefined, and alert one gives me name of first song in Songs. That means var Songs is filled with data, but when I want it to return to controller its empty ...
Am I doing something wrong here, I would appreciate any help?
Upvotes: 0
Views: 201
Reputation: 2596
First it looks like your dataFactory.getDataById is async call. Because of this what is actually happening is you returns an empty Songs array before it gets populated when all your async calls returns.
To solve this I would advise to use a Promise library like bluebird to do something like this:
// note that now your service will return a promise
this.getSongsForPlaylist = function (id) {
return new Promise(function(resolve, reject) {
var promises = [];
// here in your loop just populate an array with your promises
for (var i = 0; i < SongIsOnPlaylist.length; i++){
if(SongIsOnPlaylist[i].idPlayliste == id){
promises.push( dataFactory.getDataById(mp3fileUrl, SongIsOnPlaylist[i].idPjesme) )
}
}
// now use the library to resolve all promises
Promise.all(promises).then( function (results) {
//HERE YOU WILL GET the results off all your async calls
// parse the results
// prepare the array with songs
// and call
resolve(Songs);
});
});
}
Then you will use the service like this:
$scope.getSongsInPlaylist = function() {
var playlistId = this.item.idPlayliste;
songInPlaylistFactory.getSongsForPlaylist(playlistId)
.then(function(Songs){
$scope.Mp3Files = Songs
})
.error(function(err){
//here handle any error
});
}
Upvotes: 1