0

I'm having an issue with passing a variable from my controller to a partial asynchronously. What I'd like to happen is for a form to be rendered on my view after the user selects an option from a drop down menu. The problem is that I keep getting this error:

undefined local variable or method `shipment_options' for #<#    <Class:0x007f92941be8f0>:0x007f929ca78ad8> 

even if I use something like locals: { var: @var } or something like that. Here's the code from my view:

<body>
  <p>
    This is the body<br>

    <%= select_tag :service, options_for_select(usps_services), { id: "service_select", remote: true } %><br>

  <div id='shipment_option'>
    <%= render 'shipment_option', remote: true, locals: { shipments: @shipment_options } %>

  </div>
</body>
<script>
$('#service_select').on('change', function () {
    var service = $('#service_select').val();
    $.ajax({
      type: "POST",
      url: '/service_select',
      format: 'js',
      data: { service: service, order_id: <%= params[:order_id] %> },
      success: function (data) {
        console.log(data.rates);
        return true;
      },
      error: function (data) {
        return false;
    }});

});
</script>

The route that handles that AJAX request

# AJAX
# get '/ajax/:service' => 'dashboards#get_shipment'
post '/service_select' => 'dashboards#get_shipment'

The get_shipment method in the controller

def get_shipment
  order = Order.find(params[:order_id])
  respond_to do |format|

  from_address = EasyPost::Address.create(
    :street1 => Rails.configuration.from_address[:street1],
    :street2 => Rails.configuration.from_address[:street2],
    :city => Rails.configuration.from_address[:city],
    :state => Rails.configuration.from_address[:state],
    :zip => Rails.configuration.from_address[:zip]
  )

  to_address = EasyPost::Address.create(
    :name => order.name,
    :street1 => order.street1,
    :street2 => order.street2,
    :city => order.city,
    :state => order.state,
    :zip => order.zip
  )

  parcel = EasyPost::Parcel.create(
    :predefined_package => params[:service],
    :weight => 10
  )

  @shipment_options = EasyPost::Shipment.create(
    :to_address => to_address,
    :from_address => from_address,
    :parcel => parcel
  )
  # format.json { render json: ActiveSupport::JSON.encode(shipment_option) }
  format.js { render json: @shipment_options, action: "new" }
end 

end

And the code in the partial that I'm trying to render

<%= form_for(@shipment) do |f| %>
  <% shipment_options.rates.each do |rate| %>
    <%= f.label :shipment_service %> 
    <%= rate.service + " " + rate.rate.to_s %>
    <%= f.check_box :shipment_service %>
  <% end %>
  <%= f.submit "Ship package" %>
<% end %>

How can I get rid of this error? Thanks.

2 Answers 2

1

It looks like you passed @shipment_options as shipments to your partial, but in your partial you are calling shipment_options, which hasn't been defined.

Sign up to request clarification or add additional context in comments.

3 Comments

Well even after changing @shipment_options to shipments as I've passed in the locals variable, I'm still getting the same undefined method error.
I think that the error happens because the page is trying to render my partial before there's even been an AJAX call. I just don't know how to make rails "wait" to evaluate/load the partial until after the variable has been set in the controller. I did get this working with just javascript, but I couldn't replicate just using Ruby.
Oh I see. I assumed you had another controller (which renders the template) that also defines @shipment_options'. You actually don't need the ajax request at all if you define @shipment_options there. What is in your controller that renders the view?
0

Ok, I fixed the problem by taking out all of the arguments from format.js in my controller, and then making the .js.erb to get_shipment.js.erb. This then set my @shipment_options before I rendered the partial by writing:

$('#shipment_option').html("<%= j(render 'shipment_option') %>");

The form then rendered properly because I had set the instance variable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.