Shan Robertson
Shan Robertson

Reputation: 2742

Angular API calls and promises

I'm working on an angular app and having a difficult time with one seemly simple operation. Basically, I'm making a call to the soundcloud api, grabbing my tracks, then looping through those tracks and grabbing the iframe embed object, injecting that into the tracks object then sending that whole thing as a promise to be resolved and stored in a $scope.soundcloud object. Just fyi, the second SC call is necessary to generate the widget html. I wish it wasn't but it is hah.

This all happends as it should and i can see the object in $scope. My template picks up the initial data (main track data), and console.logging the object shows the track and embed data, but the template NEVER sees the embed data.

So, fundamentally, How do I get my template to see the embed data, so i can use it with a directive or ng-bind-html? Below is all my code, please ask if you need any more information! Thank you all very much.

HTML

<div class="track" ng-repeat="track in soundcloud.tracks">
    <div class="front">
        <img src="app/img/loading.gif" />
    </div>
    <div class="back" ng-bind-html="{{track.oembed}}">
    </div>
</div>

Angular Service

        getTracks: function(){
            var deferred = $q.defer();
            var promise = deferred.promise;

            SC.get("/me/tracks", function(tracks){
                $.each(tracks, function(k, v){
                    if(v.sharing != 'private'){
                        SC.oEmbed(v.uri, function(oembed){

                            v.oembed = $sce.trustAsHtml(oembed.html);

                        });
                    } else {
                        v.oembed = null;
                    }
                });
                deferred.resolve(tracks);
            });


            return $q.all({tracks: promise});
        }

Angular Controller

    .controller("GridCtrl", ['$scope', 'Soundcloud', function($scope, Soundcloud){

        // Init the Soundcloud SDK config
        Soundcloud.initialize();

        // Get the tracks from soundcloud
        Soundcloud.getTracks().then(function success(results){

            // Store tracks in the $scope
            $scope.soundcloud = results;
            console.log(results);

        });


    }]);

Upvotes: 0

Views: 983

Answers (1)

alexandrin88
alexandrin88

Reputation: 4400

Try creating a directive like this:

app.module('yourModule').directive('embedTrack', function() {
    return function(scope, elem, attr) {
        elem.replaceWith(scope.track.oembed);
    };
});

You then use it like this:

<div class="track" ng-repeat="track in soundcloud.tracks">
    <div class="front">
        <img src="app/img/loading.gif" />
    </div>
    <div class="back">
        <div embed-track></div>
    </div>
</div>

In case you want to pass it as an attribute to the directive, you need to use attr.$observe to make sure you get the value after the interpolation.

<div embed-track={{ track.oembed }}></div>

The directive would then be:

app.module('yourModule').directive('embedTrack', function() {
    return function(scope, elem, attr) {
        attr.$observe('embedTrack', function(value) {
            elem.replaceWith(value);
        });
    };
});

Upvotes: 1

Related Questions