user3266824
user3266824

Reputation: 1263

500 internal server error in rails with ajax

I am trying to make a text box that displays a list of sorted users that sorts per every typed letter. From there the person can add the user as a collaborator. The result should be kind of like facebook's search feature when you are searching to add new friends. When I press a key I see a new 500 internal server error in the network section of the browsers console. Here is a snippet of the response:

 <h1>
    NoMethodError
      in CollaborationsController#collaboration_search
  </h1>
</header>

<div id="container">
  <h2>undefined method `[]&#39; for nil:NilClass</h2>

So I think the ajax is getting fired to the server but there is something wrong with the controller. Here is my code for the view, views/collaborations/_new.html.erb:

    <%= form_for [wiki, collaboration] do |f|%>

<div class = "col-md-8">

    <div class = "form-group">
      <%= f.label :user_name %>
      <%= f.text_field :user_name, class: 'form-control', placeholder: "Enter name"  %>

    </div>
    <div class = "form-group">
      <%= f.submit class: 'btn btn-success' %>
    </div>
  </div>
  <%= @users_by_name.to_a %>
</div>

  </div>

</div>
<%end%>

where the form above is a partial. The ajax is written in javascripts/collaborations.js: $(document).ready(function() { // alert(1);

 $('#collaboration_user_name').on('keyup', function() { 

      // text = $(this).val();
      // alert(text);

       $.ajax({ url: "/collaborations", 
       beforeSend: function( xhr ) { 
        xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); 
      } 
     }).done(function( data ) { 
      if( console && console.log ) { 
        console.log( "Sample of data:", data.slice( 0, 100 ) ); 
        //alert()

      } 
    });
 });
});

Here is the collaboration#search_collaboration action within the collaborations controller:

 def collaboration_search
  name_search = params[:collaboration][:user_name].to_s
  @users_by_name = User.where('name Like ?', "%#{params[:collaboration][:user_name]}%")
   render json: @users_by_name.map do |user|
     { name: user.name, id: user.id}
  end

end

And just for testing purposes I kept my collaborations/search_collaboration.js.erb very simple:

alert('hello');

however if someone can point me in the right direction for how to list the names of the users returned from the collaboration_search action that would be much appreciated!

Upvotes: 1

Views: 1047

Answers (2)

Sasha
Sasha

Reputation: 6466

The error seems to suggest that you're trying to index into something as a hash, when it is, in fact, nil:

undefined method `[]&#39; for nil:NilClass

The [] refers to hash indexing -- such as params[:collaboration]. My immediate guess would be that you're not serving the params to this controller action in the format expected, so that params[:collaboration] is nil, and you're trying to index into that params[:collaboration][:user_name], provoking said error.

This jives with your current jQuery code, which doesn't send the data at all (where are you sending text as a parameter, either in the querystring or as a jQuery.ajax() param?), not to mention in that specific format.

You could either do something like this:

$.ajax({ url: "/collaborations?collaboration=#{text}",
   #..etc

Or you could use the ajax function's data method to give it a parameter as a hash instead of just throwing it in the URL. The docs for that function should give you more information.

I'd strongly recommend the latter, as you expect nested hashes in your controller [:collaboration][:user_name], which is not easily supported in a querystring parameter.

To see what the parameters are coming in as, I suggest throwing something like this in your Ruby controller:

puts "PARAMS: #{params.inspect}"

That should go above anything causing an error. It will print out the params in your server log (the terminal tab where you typed rails server or rails s), so that you can see what the parameters are, and whether this hypothesis is accurate, and how to fix the problem.

As a final note, I don't think you're actually hitting your .js.erb file at all. Your action just returns a response to the jQuery ajax function. That response is in your function called on done(), and the response data is, in your current code, referred to as data. I'd alert that data once you've gotten past this error, to see how your controller is serializing things. And then, without that js.erb file, you can simply update the DOM with the results from the jQuery.

(Final note, I can't think of an occasion where you'd need to test for if console && console.log, and I'm not sure that test won't throw an error. I might be wrong, though.)

Upvotes: 1

xander-miller
xander-miller

Reputation: 529

The UX Jargon for what you what you are trying to build is autocomplete dropdown or autocomplete combobox. It is actually a fairly complicated UI element that I wouldn't both programming from scratch. You should use a library like JQuery. JQuery is built into core Rails so I should just be a matter of including the right library. Here Is a sample of the element from JQuery.

http://jquery-ui.googlecode.com/svn/tags/1.8.7/demos/autocomplete/combobox.html

You can look at the source code using the browser development tools

Here is JQuery Autocomplete docs

http://jqueryui.com/autocomplete/

You can look at the code in you

Here is another implementation http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxcombobox/index.htm

Upvotes: 0

Related Questions