title: When using Session variables to control my embedded YouTube player, I receive the error: Uncaught TypeError: Cannot call method 'postMessage' of null?
body: <p><a href="http://mixtape.meteor.com" rel="nofollow">A link to the page where it is deployed</a></p>
  
  <p>After attempting to control using Session, the YouTube embedded player stops being responsive, and returns the error: <code>Uncaught TypeError: Cannot call method 'postMessage' of null</code>. This doesn't happen everytime, but can be reproduced by entering a song in the link and clicking on the play button.</p>
  
  <p>Here is the setting up of the YouTube API temporarily placed in the HTML file: </p>
  
  <p><code>mixtape.html</code></p>
  
  <pre><code>&lt;script&gt;
  // Called automatically when JavaScript client library is loaded.
  function onClientLoad() {
      gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
  }
  
  // Called automatically when YouTube API interface is loaded
  function onYouTubeApiLoad() {
      gapi.client.setApiKey('AIzaSyD1VcsNnysOY6_Za-8kE-BK6Zh8jQwvo4w');
  }
  &lt;/script&gt;
    &lt;script src="https://apis.google.com/js/client.js?onload=onClientLoad"&gt;&lt;/script&gt;
    &lt;script src= "https://www.youtube.com/iframe_api"&gt;&lt;/script&gt;
    &lt;script&gt;
    // Load the IFrame Player API code asynchronously.
    var tag = document.createElement('script');
    tag.src = "https://www.youtube.com/player_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  
    // Replace the 'ytplayer' element with an &lt;iframe&gt; and
    // YouTube player after the API code downloads.
    var player;
    function onYouTubePlayerAPIReady() {
      console.log("playerAPIready");
      player = new YT.Player('ytplayer', {
        height: '400',
        width: '640',
        videoId: 'M7lc1UVf-VE',
        events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
        }
      });
  
   //console.log("loaded");
    $("#player").hide();
    }
  
  function onPlayerReady(){
  //console.log("ready");
  }
  
  function onPlayerStateChange(){
  //console.log("changed");
  
  }
  
  function generatePlaylist(list){
      console.log("list: ", list)
      player.loadPlaylist(list);
  }
    &lt;/script&gt;
  </code></pre>
  
  <p>And the printing out occurs here. The nav_playlist reads from a Session variable which contains what it should, but the printing out below pretens that nav_playlist is empty. </p>
  
  <pre><code>&lt;template name="player"&gt;
      &lt;div id="player"&gt;
          &lt;div id="ytplayer"&gt;&lt;/div&gt;
          &lt;div id="nav"&gt;
              &lt;br&gt;
              {{#each nav_playlist}}
                    {{&gt; unremovable_track}}   
              {{/each}}
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/template&gt;
  </code></pre>
  
  <p>```</p>
  
  <p>An in <code>mixtape.js</code></p>
  
  <p>```</p>
  
  <pre><code>  Template.player.nav_playlist = function(){
      return Session.get("current_list");
    }
  </code></pre>
  
  <p>```</p>
  
  <p>And here are the Session variables being given their values. These contain exactly what they should. They update when the user clicks the play button. </p>
  
  <pre><code>/*Update List on generate button*/
  Template.list.updateList = function(){
      var ret = [];
          $( "#playlist .list_element" ).each(function() {
      if($(this).is(':visible')){
          ret.push(   Links.findOne({_id:$(this).attr('id')})   );
           }
      });
  
      var urls = [];
      for (var i = 0; i &lt; ret.length; i++){
          urls[i] = ret[i].videoId;
      }
  
      Session.set("current_list",ret);
      Session.set("current_urls",urls);
  }
  </code></pre>
  
  <p>And finally this is where the toggling happens to unhide the YouTube player and start the video.</p>
  
  <pre><code>  Template.header.events({
      'click #generate_button': function (evt, template){
          //bad code below:
  
      Template.list.updateList();
  
      if (Template.list.my_playlist().fetch().length == 0){
  
          alert('Your tape is empty!');
      }
      else{
          generatePlaylist(  Session.get("current_urls")  );
          $("#playlist").css('display','none');
          $("#player").fadeIn(1000);
  
          $(".absolute_center").hide();
  
          /*Things to hide*/
          $(".absolute_center2").fadeIn();
  
          $("#query").hide();
          $("#share").fadeOut(1000);
          $("#playlist_container").fadeOut(1000);
  
          $('body').animate({backgroundColor: 'rgb(53,53,53)'}, 'slow');
          $('#title').animate({color: '#fff'}, 'slow');
      }
      },
  
      'click #close_player': function (evt, template){        
          player.stopVideo();
          $(".absolute_center2").hide();
          $("#player").hide();
          $("#playlist").css('display','block');
  
          /*Things that must reappear*/
          $("#query").show();
          $("#share").fadeIn(1000);
          $(".absolute_center").fadeIn(1000);
          $("#playlist_container").fadeIn(1000);
  
          $('body').animate({backgroundColor: '#fff'}, 'slow');
          $('#title').animate({color: '#000'}, 'slow');
  
      }
  
    });
  </code></pre>
  
  <p><a href="https://github.com/alouis93/music-meteor" rel="nofollow">Here is the GitHub page if you would like to look at the source and dig deeper</a></p>