2

I'm new to angularJS and i'm having some issues with the below code. Basically what i'm trying to achieve is to search the spotify API for a term and retrieve the first playlist given to me, then grab the URI of the playlist and concatenate it to an embed url to be displayed in a page.

I can't seem to get the $scope.spotifySearch object to go into the $scope.playlisturi scope in a string format. any help would be appreciated.

app.controller('MainCtrl', function ($scope, $sce, Spotify) {

  $scope.spotifySearch = Spotify.search('Top 40', 'playlist').then(function (data) {
    return (data.playlists.items[0].uri);
  });

  $scope.trustSrc = function(src) {
    return $sce.trustAsResourceUrl(src);
  }

  $scope.playlisturlfragment = "https://embed.spotify.com/?uri=";
  $scope.playlisturi = $scope.spotifySearch;
  $scope.playlisturl = {src:$scope.playlisturlfragment+$scope.playlisturi}

});
ThallerThanYall
  • 197
  • 2
  • 14

3 Answers3

2

You are assigning a promise to spotifySearch and I think what you want is the uri returned by the search.

There are basically two approaches to this problem.

  1. Assign the value to playlisturl when the promise is resolved.
  2. Assign the value to playlisturl when spotifySearch is changed.

Here's the first approach.

 $scope.playlisturlfragment = "https://embed.spotify.com/?uri=";
 Spotify.search('Top 40', 'playlist').then(function (data) {
     $scope.playlisturl = {src:$scope.playlisturlfragment+data.playlists.items[0].uri}
  });

The other way is to watch spotifySearch for changes.

 $scope.playlisturlfragment = "https://embed.spotify.com/?uri=";
 Spotify.search('Top 40', 'playlist').then(function (data) {
     $scope.spotifySearch = data.playlists.items[0].uri;
  });

 $scope.$watch('spotifySearch',function(value) {
     if(!value) return;
     $scope.playlisturl = {src:$scope.playlisturlfragment+value};
 });
Reactgular
  • 52,335
  • 19
  • 158
  • 208
  • why add the watch and not just update `$scope.playlisturl` in callback? Also might need `$apply` – charlietfl Oct 20 '15 at 14:01
  • First approach works perfectly, thanks for the help, I realise where I was going wrong now :) – ThallerThanYall Oct 20 '15 at 14:02
  • I would opt for the first one – devqon Oct 20 '15 at 14:02
  • @charlietfl it's good to split logic from DOM related things. Perform the Spotify.search in the directive's controller, and update the DOM in the link. – Reactgular Oct 20 '15 at 14:02
  • I look your example. You use the $watch for wait the return of promise. For me this is ant-pattern. Use the $watch in development big projects can hurt the code if development changes the model in other part of code. The callback function guarantee unique comportament in app. In the situation you necessity two comportament. Whats you do? Create other variáble for $watch this? – Emir Marques Oct 20 '15 at 14:18
1

You assign a promise to your $scope.spotifySearch, not the real data ($http returns a promise). Instead you can do it like this:

app.controller('MainCtrl', function ($scope, $sce, Spotify) {

    $scope.playlisturlfragment = "https://embed.spotify.com/?uri=";
    $scope.playlisturl = {
        src: ""
    }

    $scope.spotifySearch = Spotify.search('Top 40', 'playlist').then(function (data) {
        // use the callback to assign the uri to your object
        $scope.playlisturl.src = $scope.playlisturlfragment + data.playlists.items[0].uri;
    });

});
devqon
  • 13,818
  • 2
  • 30
  • 45
0

Angular use promise for request. This promise is async, soon return value in then not work. For this use the callback function as:

app.controller('MainCtrl', function ($scope, $sce, Spotify) {

    $scope.trustSrc = function(src) {
        return $sce.trustAsResourceUrl(src);
    };

    $scope.init = function(){
        $scope.search(function(uri){
            $scope.playlisturlfragment = "https://embed.spotify.com/?uri=";
            $scope.playlisturl = {src:$scope.playlisturlfragment + uri};
        });
    };

    $scope.search = function(callback){
        $scope.spotifySearch = Spotify.search('Top 40', 'playlist').then(function (data) {
            callback(data.playlists.items[0].uri);
        });
    };
});

Run the init method for look this example

Emir Marques
  • 2,603
  • 2
  • 16
  • 22
  • converting promises into callbacks is an ant-pattern for me. It hides the benefits of promises. – Reactgular Oct 20 '15 at 14:04
  • I look your example. You use the $watch for wait the return of promise. For me this is ant-pattern. Use the $watch in development big projects can hurt the code if development changes the model in other part of code. The callback function guarantee unique comportament in app. In the situation you necessity two comportament. Whats you do? Create other variáble for $watch this? – Emir Marques Oct 20 '15 at 14:18