1

I am trying to display an object (songTitle) from my service. The initial state (tmp) is displayed. If I am changing the object in the service, the view doesnt get updated.

Js:

var party = angular.module("party", []);

party.run(function () {
      var tag = document.createElement('script');
      tag.src = "http://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});

party.service('PlayerService', function ($window) {
      this.playlist = [
            "https://www.youtube.com/watch?v=fnW2uLwHAas",
            "https://www.youtube.com/watch?v=iPT8DA32U6U",
            "https://www.youtube.com/watch?v=eGjEnfQl37s",
            "https://www.youtube.com/watch?v=nFtTY2S20mI",
            "https://www.youtube.com/watch?v=UmXQiPLoLTk",
            "https://www.youtube.com/watch?v=PbVx85DS9zc",
            "https://www.youtube.com/watch?v=ciidn3nEoiE",
            "https://www.youtube.com/watch?v=sm0DgkBEnUI",
            "https://www.youtube.com/watch?v=J2OCSWF7sAw",
            "https://www.youtube.com/watch?v=y_-giRHtuv8",
            "https://www.youtube.com/watch?v=iPT8DA32U6U",
            "https://www.youtube.com/watch?v=eGjEnfQl37s",
            "https://www.youtube.com/watch?v=nFtTY2S20mI",
            "https://www.youtube.com/watch?v=UmXQiPLoLTk",
            "https://www.youtube.com/watch?v=PbVx85DS9zc"
      ];
      this.player = {};
      this.pbTimer = null;
      this.songTitle = "tmp";

      $window.onYouTubeIframeAPIReady = function () {
            this.player = new YT.Player('ytplayer', {
                  height: '100',
                  width: '100',
                  videoId: 'ciidn3nEoiE',
                  events: {
                        'onReady': onPlayerReady
                  }
            });
      }


      function onPlayerReady() {
            console.log("db ready");
            songTitle = player.getVideoData().title;
            console.log(songTitle);
      }

      this.playVideo = function (url) {
            console.log("db playVideo " + url);
            player.loadVideoById(url.split("watch\?v=")[1], 0, "large");
            console.log(player);

      }

});
party.controller("FrontController", function ($scope) {
      $scope.front = {};
      $scope.front.title = "PARTY";
});

party.controller("PartyController", ['$scope', 'PlayerService', function ($scope, PlayerService) {
      $scope.party = {};
      $scope.party.title = "PARTY";
      Sortable.create(playlist, { /* options */ });
      $scope.playlist = PlayerService.playlist;
      $scope.playVideo = function (url) {
            PlayerService.playVideo(url);
      }
      $scope.songTitle = PlayerService.songTitle;
}]);

HTML

<body ng-app="party">
<div ng-controller="PartyController" class="container-fluid">
...
    <p id="playertitle">{{songTitle}}</p>
...

Log:

db ready 
Blackmill Feat. Veela - Life (Full Version)
user547995
  • 2,036
  • 8
  • 33
  • 62

1 Answers1

0

The problem is in your onPlayerReady function. The line songTitle = player.getVideoData().title; doesn't set songTitle on your service, but rather on the global scope, which is the window object. Simply using this.songTitle won't help either, because this doesn't refer to your service too in the scope of onPlayerReady.

The easiest solution would be to save a reference to your service outside of onPlayerReady and then use it to assign songTitle:

var self = this;
function onPlayerReady() {
  console.log("db ready");
  self.songTitle = player.getVideoData().title;
  console.log(self.songTitle);
}

Still, this is not enough. Because you change songTitle from outside the Angular world (the Youtube player callbacks), you need to call $scope.$apply to notify Angular something has changed.

For that, you need to inject $rootScope into your service:

party.service('PlayerService', function ($window, $rootScope)

and change songTitle using $rootScope.$apply:

var self = this;
function onPlayerReady() {
  console.log("db ready");
  $rootScope.$apply(function() {
    self.songTitle = player.getVideoData().title;
    console.log(self.songTitle);
  });
}
bumpy
  • 2,002
  • 2
  • 14
  • 19
  • your answer seems legit, but the title still wont be updated on the view. I added the log to the playvideo function, which will be called aftter onPlayerReady. I see that the object is updated, but the old value is still shown on the view – user547995 Sep 06 '15 at 21:56
  • still doens't work, i guess that angular doesnt recogniese that change. I guess I have to use some solutions from http://stackoverflow.com/questions/12576798/how-to-watch-service-variables?lq=1 – user547995 Sep 06 '15 at 23:28