0

I have the following controller code:

class NodesController < ApplicationController

  def index
    @nodes = Node.com_name_scope("27").find(:all, :conditions => ['COMPONENT_NAME LIKE ?', "#{params[:search]}%"])

    respond_to do |format|
      format.js {render :js => @nodes.map { |node|  "<li>#{node.COMPONENT_NAME}</li>"}}
    end
end

When I do:

http://localhost/myproject/nodes.js

I get the following list:

<li>Value A</li>
<li>Value B</li>
<li>Value C</li>
<li>Value D</li>

I would like to insert a <ul> tag at the start and end of the list so that it look as follows:

<ul>
<li>Value A</li>
<li>Value B</li>
<li>Value C</li>
<li>Value D</li>
</ul>

But when I do:

format.js {render :js => "ul" + @nodes.map { |node|  "<li>#{node.COMPONENT_NAME}</li>"}+ "</ul>" }

It is giving me the following error message:

 TypeError in NodesController#index

can't convert Array into String

My question is how do I include the <ul> tag in front and at the end of the list.

Thanks a lot for your help

Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
Kim
  • 2,070
  • 5
  • 33
  • 46

3 Answers3

2
@nodes.map { |node|  "<li>#{node.COMPONENT_NAME}</li>"}

returns an array of strings, you need to join them in some way before merging them with the string.

format.js { render :js => "<ul>#{@nodes.map { |node|  "<li>#{node.COMPONENT_NAME}</li>"}.join}</ul>" }
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
1

You'll need to convert the array @nodes.map { } to a string:

format.js { render :js => "<ul>" + (@nodes.map { |node|  "<li>#{node.COMPONENT_NAME}</li>"}).to_s + "</ul>" }
Mark
  • 6,033
  • 1
  • 19
  • 14
  • 2
    `Array#to_s` has inconsistent behavior depending on the Ruby version. You should use `Array#join` – Simone Carletti Sep 28 '12 at 17:54
  • @SimoneCarletti: Thanks for this hint. I tested it on an older machine with ruby 1.8.4, where it worked as expected. What would be the behavior in other versions? – Mark Sep 28 '12 at 18:01
  • See http://stackoverflow.com/questions/3960392/ruby-1-9-array-to-s-behaves-differently – Simone Carletti Sep 28 '12 at 18:15
1

The following example should work:

respond_to do |format|
  format.js do
    mapped = @nodes.map { |node|  "<li>#{node.COMPONENT_NAME}</li>"}
    mapped.unshift "<ul>"
    mapped.push "</ul>"

    render :js => mapped
  end
end

But note, your code looks still strange. You respond to your :js with a html-fragment?

Deradon
  • 1,787
  • 12
  • 17