William Curry
William Curry

Reputation: 13

Fix "Cannot ready property 'container' of null" From musickit.js When Running Angular App on Server

I'm writing an application that uses Angular and MusicKit to allow users to listen to the same music at the same time. I'm encountering the following error when attempting to run the application (with ng serve --host x.x.x.x) against anything other than the default localhost (with ng serve):

core.js:14597 ERROR TypeError: Cannot read property 'container' of null  
    at Player. (musickit.js:formatted:6614)  
    at musickit.js:formatted:726  
    at Object.next (musickit.js:formatted:739)  
    at fulfilled (musickit.js:formatted:627)  
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)  
    at Object.onInvoke (core.js:16156)  
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:387)  
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138)  
    at zone.js:872  
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)  



21:08:38.100 core.js:14597 ERROR Error: Uncaught (in promise): 
TypeError: Cannot read property 'isFairplay' of undefined  
TypeError: Cannot read property 'isFairplay' of undefined  
    at MediaExtension.get [as isFairplay] (musickit.js:formatted:5020)  
    at musickit.js:formatted:6728  
    at Array.filter ()  
    at Player._playbackDataForItem (musickit.js:formatted:6726)  
    at Player. (musickit.js:formatted:6504)  
    at musickit.js:formatted:726  

I think that the "isFairplay" error is a result of whatever is causing the first one, but I included it to be safe. I'm using an nginx server on digitalocean (ng build, move the dist folder over to /var/www/html) but locally I was just using "ng serve --host x.x.x.x to run against my local IP. When just using the plain ng serve, everything works fine. I've tried with other Apple Music accounts in case Apple was confused about what application was actually making the request and I've tried in different browsers/incognito windows in Chrome.

I'm attempting to do the following: 1. Show the user a list of songs from their library 2. Allow the user to select a song 3. Subscribe to the following steps in an observable: 4. When the song is selected, queue the song with musicKit.queueSong 5. When the song is queued, use musicKit.player.play() to play the currently queued song

The following errors occur after step 5. I am already adding container.id to the song, so I believe for some reason Apple is not actually queueing the song, I'm just not sure whats happening to it afterwards. The queueSong returns successfully, so I think container.id is not the only thing null or undefined, its just the first thing it complains about.

Code describing what happens in the above steps. "playSong(..)" is subscribed to in another class:

playSong(songs: any[], index: number): Observable {  
    if(songs) {  
      //songs play without the forEach, but musicKit still complains 
      //about not finding container.id in the song object  
      songs.forEach(song => song['container'] = { 'id' : song.id });  


      return from(this.musicKitService.setQueue({ 'items': songs, startPosition: index}))  
        .pipe(mergeMap(x => this.play()));  
    }  
  }  

  modifyPlayback(arg: Observable): Observable {  
    return arg.pipe(map(x => this.setTitle()));  
  }  


  play(): Observable {  
    return this.modifyPlayback(from(this.player.play()));  
  }      

I expect after this point for the song to start playing in the browser. I'm essentially queueing a single song then telling musicKit.js to play the queued up song. However, when msuicKit.js goes to play the queued song, there is no song there to play. I'm not sure whats actually happening to the song after its successfully queued when I'm running outside of localhost.

I also posted this to the apple developer forums where I included someone with the problem from last year, but it was never resolved. https://forums.developer.apple.com/message/350355#350355

I also forgot to mention in the original post: this ONLY occurs in chrome. The code works fine in Firefox and in mobile safari.

Upvotes: 0

Views: 269

Answers (1)

William Curry
William Curry

Reputation: 13

Solution:

In chrome at least, musicKit.js requires that the site being hosted is using SSL. This was not a problem for me running everything locally, but if I even ran against my network's IP address, SSL was required. I stopped getting the errors once I set up https on my server. As far as I know this isn't documented on musicKit.js documentation, but I may have missed it.

Upvotes: 0

Related Questions