Pfeiffer
Pfeiffer

Reputation: 160

Posting from javascript to ruby

So I have this chunk of code on the view:

var variable_test = 'begin';
$.ajax({
  url : "/controller/index",
  type : "post",
  data : variable_test
}).done(function(response) {
  alert('1');
})
    .fail(function (error) {
    alert('2');
});

var eia = <%= @variable.to_json.html_safe %>;
alert(eia);

and on controller I have this:

def index
   @someVariable = 'end'
   @variable = params[:variable_test]
end

on execution this would be the result:

dialog message with 1 (so it was supposed to have worked and posted something)

dialog message with null

and this is the server side POST request:

Started POST ...  
Processing by Controller#index as */*  
Parameters: {"begin"=>nil}  
...  
...  
Current user: anonymous  
...  
Completed 200 OK... 

So what is wrong? Is it actually posting the variable variable_test to controller variable ? If yes, why does it reads it as null? How to fix this?

Upvotes: 1

Views: 193

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

The way this works is actually quite simple.

Your Ajax seems to be sending your request to your controller:

Started POST ...
Processing by Controller#index as */*
Parameters: {"begin"=>nil}

... it's your response which is not being caught...

#app/assets/javascripts/application.js
$.ajax({
  url : "/controller/index",
  type : "post",
  data : {serialized: "data"}, // data should be serialized
}).done(function(response) {
  alert('1');
}).fail(function (error) {
    alert('2');
});

This setup should trigger the alert('1') function.


Handling the response is where you're falling short:

1. ERB doesn't work in the asset pipeline

#app/assets/javascripts/application.js
var eia = <%= @variable.to_json.html_safe %>; // won't work
alert(eia); // won't work

This will not work.

What will is to use the returned data inside the ajax .done method:

#app/controllers/controller_controller.rb
class ControllerController < ApplicationController
   def index
      @variable = {}
      @variable.attribute = "test"
      respond_to do |format|
         format.json { render json: @variable }
      end
   end
end

#app/assets/javascripts/application.js
$.ajax({
  url : "/controller/index",
  type : "post",
  data : {serialized: "data"}, // data should be serialized
}).done(function(response) {
   json = JSON.parse(response);  
   alert(json.attribute)
}).fail(function (error) {
    alert('2');
});

This should return the data, allowing you to output it into the view

--

2. Use Server-Side JS

In addition to the fact that ERB won't work in the front-end, you'll have to look at how your JS is being called.

You must remember that JS is front-end; it doesn't have any access to your Ruby variables. Thus, if you're trying to access the returned data in your view, you either need to capture the response from the server (#1), or run server-side JS like this:

#app/controllers/controller_controller.rb
class ControllerController < ApplicationController
   def index
      respond_to do |format| 
         format.js #-> calls app/views/controller/index.js.erb
      end 
   end
end

This will invoke index.js.erb whenever you run the index action - allowing you use any of the data you've defined in Ruby:

#app/views/controller/index.js.erb
var eia = <%= @variable.to_json.html_safe %>;
alert(eia);

This would also have to coincide with removing the response hooks in your front-end ajax:

#app/assets/javascripts/application.js
$.ajax({
  url : "/controller/index",
  type : "post",
  data : {serialized: "data"}, // data should be serialized
});

Upvotes: 1

nbermudezs
nbermudezs

Reputation: 2844

It is sending your value in the post. The problem is that data takes an object as value, so if you want to read the value in the server side as params[: variable_test] you need to make the ajax call

var variable_test = 'begin';
$.ajax({
  url : "/controller/index",
  type : "post",
  data : { variable_test: variable_test },
}).done(function(response) {
  alert('1');
}).fail(function (error) {
  alert('2');
});

On another hand, I'm not sure what you are trying to accomplish, The index action as you have it will try to render the index.html.erb file you have under app/views/controller/, is that the same index action that is being called in the ajax request?

Sorry for not commenting, not enough reputation.

Upvotes: 2

Related Questions