David Elner
David Elner

Reputation: 5191

Rails 3: Instance variable inaccessible in .js.erb file

I'm trying to build a really simple page, where I need to generate some dynamic JavaScript for a photo gallery. Something intuitively simple, but which I'm struggling with greatly. In my controller I am building a list of Photo as @photos, then need to iterate out some JavaScript for each photo in my photo.js.erb file.

However, whenever I reach my .js.erb file, the @photos variable becomes nil... what am I missing?

controllers/photos_controller.rb file:

class PhotosController < ApplicationController
  layout "application_photos"
  def category
    @photos = ...(generates collection of Photos)...
  end
end

views/photos/category.html.haml file:

= content_for :head do
  // @photos is still initialized at this point
  = javascript_include_tag "photos"

// This partial only loads some more markup, it's inconsequential.
= render :partial => 'default_slideshow'

javascripts/photos.js.erb file:

jQuery(function($){
    // Throws NilClass error
    <% puts 'Photos: ' + @photos %>
});

I know this question has been asked a dozen times, but none of the previously accepted answers actually worked for me. Any suggestions are greatly appreciated.

Upvotes: 1

Views: 3252

Answers (1)

benchwarmer
benchwarmer

Reputation: 2774

You need to send js request to the server in order to have access to the instance variable. Something like this

$(function($){
  $.ajax({
    type: "get",
    url: "..."
    })  

});

In views/photos/category.js.erb file:

alert("<%= j @photos %>")

Or you can do the same using gon gem.

app/views/layouts/application.html.erb

<head>
 <title>some title</title>
 <%= include_gon %>
 <!-- include your action js code -->
 ...

You put something like this in the action of your controller:

@your_int = 123
@your_array = [1,2]
@your_hash = {'a' => 1, 'b' => 2}
gon.your_int = @your_int
gon.your_other_int = 345 + gon.your_int
gon.your_array = @your_array
gon.your_array << gon.your_int
gon.your_hash = @your_hash

gon.all_variables # > {:your_int => 123, :your_other_int => 468, :your_array => [1, 2, 123], :your_hash => {'a' => 1, 'b' => 2}}
gon.your_array # > [1, 2, 123]

gon.clear # gon.all_variables now is {}

Access the varaibles from your JavaScript file:

alert(gon.your_int)
alert(gon.your_other_int)
alert(gon.your_array)
alert(gon.your_hash)

Hope this helps

Upvotes: 3

Related Questions