Reputation: 461
I've read/researched other answers, but I can't get this to work. I have a js.erb file that is rendering a partial. I'm looking to pass a @node variable to it but I get an error in the console NameError: - undefined local variable or method "node" for #<#<Class:0x007fdcd9163510>:0x007fdcd813b728>
I'm not sure why it won't grab it.
<div id="tagged_users">
<%= render partial: "nodes/user_tag_list", locals: { node: node } %>
</div>
partial that I would also like rendered in js.erb
<ul>
<% node.tagged_users.map(&:name).each do |tag| %>
<li><%= tag %>
<%= link_to "x", node_path(node, remove_tag: tag), method: :patch %>
</li>
<% end %>
</ul>
def update
@node = Node.find(params[:id])
if params.fetch(:node, {}).fetch(:autocomplete_tag_names, false)
tag = params[:node][:taggable_email]
@node.user_tag_list.add(tag)
@node.save
respond_to do |format|
format.js { render 'user_tag_add.js.erb' }
end
elseif
# ...
else
# ...
end
and finally, the js.erb file:
$("#tagged_users").html("<%= escape_javascript(render 'user_tag_list', locals: { node: @node }) %>");
A couple of notes. The logic is sound. If I replace the html with a string rather than the partial it works fine. Also, if I binding.pry
I can set node to @node without issue. Just can't get the @node to pass to node within the js.erb file.
EDIT
Here's the form partial, if useful:
<%= form_for node, remote: true, html: { class: "edit_node tag-users" } do |f| %>
<%= f.label :autocomplete_tag_names %>
<%= f.text_field :autocomplete_tag_names, data: { autocomplete_source: users_path }, value: nil %>
<%= f.hidden_field :taggable_email, value: nil %>
<%= f.submit %>
<% end %>
Upvotes: 3
Views: 5145
Reputation: 461
Ugh, it wasn't the variable scope at all. In my js.erb file above I originally had:
$("#tagged_users").html("<%= escape_javascript(render 'user_tag_list', locals: { node: @node }) %>");
Notice that above I said user_tag_list was a partial? Well, I didn't specify that in my render statement. I needed to modify the code to the following:
$("#tagged_users").html("<%= escape_javascript(render partial: 'user_tag_list', locals: {node: @node}) %>");
Then it worked. If anyone else is having issues debugging this type of code to see if it's the variable or not, I went through the following steps creating console messages:
Make sure the variable can be seen
console.log("<%= @node %>"); response: #<Node:0x007fdcd8203138>
To confirm I wrote a couple of console statements that would extract something out of the object to make sure the correct information was being captured
console.log("<%= @node.id %>"); response: 49
console.log("<%= @node.name %>"); response: 'Test 2'
Once I saw that the variable was being passed I knew this wasn't the issue, and it looked to make sure I had my render
statement properly formatted. Missing partial
was a big mistake that cost me a few hours of my life. I hope this post saved got you some time back.
Additional Info
One other thing I learned while debugging this: If you ever want to set a local variable rather than an instance variable (for whatever reason I'm not sure) you can create it in your render statement within your controller action
respond_to do |format|
format.js { render 'user_tag_add.js.erb', locals: {node: @node} }
end
Then you could do something like this within your js.erb file
console.log("<%= node %>")
Upvotes: 8