Liz Liz - 5 months ago 9
Javascript Question

AJAX Object Creating, but Not Appearing Until Manual Refresh

I am building a basic to do app with various

lists
each of which
has_many
items
. I'm trying to implement AJAX on the list creation and display on the
lists#index
page. The new lists are created okay, but they don't appear until I manually refresh the page. Here is the error, as described in the server log:

List Exists (0.1ms) SELECT 1 AS one FROM "lists" WHERE ("lists"."id" IS NOT NULL) AND "lists"."slug" = ? LIMIT 1 [["slug", "new-list-again"]]
SQL (0.3ms) INSERT INTO "lists" ("name", "shared_with", "user_id", "slug") VALUES (?, ?, ?, ?) [["name", "New List Again"], ["shared_with", ""], ["user_id", 2], ["slug", "new-list-again-dc08b63c-1d57-42ea-a725-a2c5c185e529"]]
(0.7ms) commit transaction
Rendered lists/create.js.erb (7.9ms)
Completed 500 Internal Server Error in 22ms (ActiveRecord: 1.4ms)

NoMethodError - undefined method `valid?' for nil:NilClass:
app/views/lists/create.js.erb:1:in `_app_views_lists_create_js_erb___822718317456566494_70187652289300'


Here is the relevant code on my
lists#index
page:

<h1>My Lists (<%= @lists.count %>)</h1>
<% if @lists.count == 0 %>
<p>You don't have any lists yet! Why don't we remedy that?<p>
<% end %>

<div class='list-form'>
<%= render partial: 'lists/form', locals: { list: @list } %>
</div>

<div class="js-lists">
<%= render @lists %>
</div>


Here is my
lists/_form
partial:

<div class="row">
<div class="col-xs-12">
<%= form_for @list, format: :js, remote: true do |f| %>
<div class="form-group col-sm-6">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter List Name" %>
</div>

<div class="form-group col-sm-6">
<%= f.label 'Share My List (Not Required)' %>
<%= f.text_field :shared_with, class: 'form-control', placeholder: "Enter Emails Separated by Commas" %>
</div>

<div class="text-center"><%= f.submit "Let's Go!", class: 'btn btn-primary' %></div>
<% end %>
</div>
</div>


Here is my
lists/_list
partial:

<%= link_to list_path(list) do %>
<h4><%= list.name %>
<% if list.shared_with != "" %>
(Shared)
<% end %>
<% end %>
<small>( <%= list.items.count %> Items, <%= link_to "Edit", edit_list_path(list) %> | <%= link_to "Delete", list_path(list), method: :delete %> )</small></h4>


Here is my
create.js.erb
file:

<% if @item.valid? %>
$('.js-lists').prepend("<%= escape_javascript(render partial: 'lists/list', locals: { list: @list }) %>");
$('.list-form').html("<%= escape_javascript(render partial: 'lists/form', locals: { list: @new_list }) %>");
<% else %>
$('.flash').prepend("<div class='alert alert-danger'><button type='button' class='close' data-dismiss='alert'>&times;</button><%= flash.now[:alert] %></div>");
$('.new-list').html("<%= escape_javascript(render partial: 'lists/form', locals: { list: @list }) %>");
<% end %>


And here is the
create
method in my
lists_controller
:

def create
@list = List.new(list_params)
@list.user = current_user
@new_list = List.new

if @list.save
flash[:notice] = "Your list was saved successfully."
else
flash.now[:alert] = "Error creating list. Please try again."
end

respond_to do |format|
format.js
end
end


I'm relatively new to Ruby, but extremely new to Javascript, so I would appreciate if anyone could help point out where I'm going wrong here. The new
list
is definitely being created, it just doesn't show up until you manually refresh the page.

Answer

Looks like you've got the wrong variable name in create.js.erb. You should be checking the validity of @list, not @item

Comments