Back navigation not reloading jwplayer in backbone js and rails 3 app-Collection of common programming errors

My app is a rails 3 app using backbone.js and jw player for playing a playlist of videos. The index_view for the videos has all the videos loaded into a playlist for jw player. My problem comes when I navigate away from the index page, let’s say to the show_view for an individual video. When I click the browser’s back button I get an error when the jw player tries to load again.

Uncaught TypeError: Object # has no method 'setup' 

I believe the problem is that the template hasn’t loaded the html element that the player uses to instantiate itself. That’s my current theory. If you look in index_view.js.coffee you see that in the render method I use the JQuery $(document).read -> method to load the player. If I remove that, the player doesn’t load and I see the same error.

Uncaught TypeError: Object # has no method 'setup' 

This error can be reproduced simply by calling the jwplayer on a non-existant CSS id. ie jwplayer('non-existant-id').setup(...) would produce the same error. I’m pretty new to backbone but I would assume that the JQuery document.ready method has no effect after the initial loading of the index page. The DOM is never reloaded once I’m using the # routes, so when I navigate back to the index page, the id ‘my-video’ doesn’t yet exist so calling jwplayer('my-video') produces an error. Is there any sort of Backbone.ready method? 🙂

So here’s some code, lemme know if you need anything else:

index.html.erb The rails view for videos




  $(function() {
    // Blog is the app name
    window.router = new SeehearmeWebapp.Routers.VideosRouter({videos: , users: , questions: });
    Backbone.history.start();
  });

videos_router.js.coffee

class SeehearmeWebapp.Routers.VideosRouter extends Backbone.Router
  initialize: (options) ->
    @videos = new SeehearmeWebapp.Collections.VideosCollection()
    @videos.reset options.videos
    @users = new SeehearmeWebapp.Collections.UsersCollection()
    @users.reset options.users
    @playlist = []
    @questions = options.questions
    for i in [[email protected]]
      video = @videos.models[i]
      versions = video.attributes.versions[6]
      images = video.attributes.thumbnails[0]
      question = @questions[parseInt(video.attributes.question_id)-1]
      if !(question == undefined)
        title = question.text
      else
        title = ""

      if !(versions == undefined)
        creator_id = video.attributes.creator_id.toString()
        @playlist.push {file: versions.url, creator_id: creator_id, gender: @users.get(creator_id).attributes.gender, question: title ,  image: images.url}

  routes:
    "new"      : "newVideo"
    "index"    : "index"
    ":id/edit" : "edit"
    ":id"      : "show"
    ".*"        : "index"

  newVideo: ->
    @view = new SeehearmeWebapp.Views.Videos.NewView(collection: @videos)
    $("#videos").html(@view.render().el)

  index: ->
    @view = new SeehearmeWebapp.Views.Videos.IndexView(videos: @videos, users: @users, playlist: @playlist)
    $("#videos").html(@view.render().el)

  show: (id) ->
    video = @videos.get(id)

    @view = new SeehearmeWebapp.Views.Videos.ShowView(model: video)
    $("#videos").html(@view.render().el)

  edit: (id) ->
    video = @videos.get(id)

    @view = new SeehearmeWebapp.Views.Videos.EditView(model: video)
    $("#videos").html(@view.render().el)

index_view.js.coffee

SeehearmeWebapp.Views.Videos ||= {}

class SeehearmeWebapp.Views.Videos.IndexView extends Backbone.View
  template: JST["backbone/templates/videos/index"]

  playerHeight = '360'
  playerWidth = '640'
  defaultVersion = 0
  playlist = []

  initialize: () ->
    @options.videos.bind('reset', @addAll)
    playlist = @options.playlist

  addAll: () =>
    @options.videos.each(@addOne)

  addOne: (video) =>
    view = new SeehearmeWebapp.Views.Videos.VideoView({model : video})
    @$("tbody").append(view.render().el)

  render: =>
    $(@el).html(@template(videos: @options.videos.toJSON() ))
    @addAll()

    $(document).ready ->
      player = jwplayer('my-video')
      player.setup({playlist: playlist,  width: playerWidth, height: playerHeight, skin: "/jwplayer/skins/six/six.xml"})

    return this

index.jst.ejs


    
        Show Me: 
        
            Women and Men
            
                
            
            
        
    
    
    

seehear.me

    
    
    
        
        meet her
        
    


show_view.js.coffee

SeehearmeWebapp.Views.Videos ||= {}

class SeehearmeWebapp.Views.Videos.ShowView extends Backbone.View
  template: JST["backbone/templates/videos/show"]

  render: ->
    $(@el).html(@template(@model.toJSON() ))
    return this

show_view.js.coffee

THIS IS A VIDEO


Back

Thanks!