Issue passing parameter to Rails controller using AJAX - javascript

I'm wanting to send a post request from my JavaScript code to my show action in Ruby on Rails which contains data that I want to store in an instance variable so I can save it on a form in my view and upload it to my server.
As you can see below, the parameter 'base64' is showing up in my rails logs, but when I try to call #base64 in my view, after grabbing the value in the controller, it's nil.
Any advice is appreciated, thanks!
View
var full_base64 = "data:image/jpeg;base64," + base64;
$.ajax({
data: 'base64=' + full_base64,
type: 'POST',
url: "/videos/show/<%=#video.id%>"
});
Controller
def show
#video = Video.find(params[:id])
if params[:base64].present?
#base64 = params[:base64]
end
end
Routes
post 'videos/show/:id', to: 'videos#show'
Rails server log:
Started POST "/videos/show/1" for 127.0.0.1 at 2020-01-22 12:59:40 -0600
Processing by VideosController#show as */*
Parameters: {"base64"=>"data:image/jpeg;base64,iV...
...
, "id"=>"1"}
Console
>>
#base64
=> nil
>>

If I understand correctly you are trying to pass AJAX to the show action in your controller. This is a very GENERALIZED answer as you have failed to include any of your HTML code and it looks like you don't have a button to fire the AJAX. But I'll try to point you in the right direction. You need to do something along the general lines of:
var full_base64 = "data:image/jpeg;base64," + base64;
$.ajax({
data: 'base64=' + full_base64,
type: 'POST',
url: "/videos/my_ajax_upload"
});
That will send your AJAX call to a controller method I've called my_ajax_upload but you can call it whatever you like. In your controller you would need something like:
def my_ajax_upload
#video.update(base_64: params[:base64])
respond_to do |format|
format.js {render :action => "base_64_response" }
end
end
This responds to the initial AJAX call by saving the param you sent to the DB and replying by calling a file called base_64_response.js.erb which might look something like:
$('#pic_upload').html('<%= escape_javascript(render :partial => 'base_64_response') %>');
Which will render the HTML file called base_64_response.html.erb which needs to contain the html code you want to appear in the page that called it.
<div id="pic_upload">
<%= #base64 =>
</div>
The cycle is load page -> do something to trigger AJAX call to controller method -> process AJAX call with controller method -> render JS file -> JS file replaces div in page with new html
You probably need to read up more on how AJAX works in Rails. This RailsCast might help http://railscasts.com/episodes/136-jquery-ajax-revised?view=asciicast

Just FYI - I have also noticed strange things in Rails if you do not explicitly define the content type. In your posted example you are not stating the contentType and it could be parsing nil for that reason. When posting base 64 data you can specify the content type as:
$.ajax({
data: 'base64=' + full_base64,
type: 'POST',
contentType: 'application/octet-stream'
url: "/videos/show/<%=#video.id%>"
});
and it may change what the controller parses for the body.
How to post an image in base64 encoding via .ajax?

Just use string instead of symbol for hash key
if params["base64"].present?
#base64 = params["base64"]
end

Related

Rails 5: Respond to AJAX call with HTML (instead of javascript)

(Rails version 5.1.2)
I would like to respond to AJAX with HTML rather than javascript for much the same reasons as outlined in this stack overflow question.
However, I can't actually get it to work.
I'm using form_for with remote: true to send the request via AJAX. Note that I've also experimented with data: {type: :html}.
My controller action has the line render layout: !request.xhr? and has an associated view. It's this view that I want sent back to the client.
Yet the client-side code:
$("form").on('ajax:success', (e, data, status, xhr) ->
console.log xhr.responseText #using console.log data produces same result
)
Gives:
Turbolinks.clearCache()
Turbolinks.visit("http://localhost:3000/...", {"action":"replace"})
Where's the HTML?
Unless I am completely misunderstanding what you want to do, this should be what you are looking for:
Javascript:
$.ajax({
// remember to add this route to your routes file
url: "products/ajax_render",
success: function(data){
$('.some_div').html(data['html'])
},
});
Ruby on Rails:
def ajax_render
# render some view and store it in a variable
html = render "products/your_view"
# return it inside the json response
render json: { html: html }
end
Am I missing something?

Sending an AJAX request to rails controller, then a HTTParty to external service, which returns JSON to output in .html.erb file

I am attempting to send an AJAX response to my rails controller, which will then send a HTTParty request to an external service. I am doing it this was because their would be a CORS issue if I sent a AJAX request straight from the JS. After the HTTParty, I need to receive the JSON it returns and output that on the .html.erb file. It seems complicated, but I just need a little bit of assistance implementing its functionality;
We begin by sending the AJAX request to our rails backend by doing the following.
$.ajax({
url: "/gametitle",
type: "post",
data : {title: gametitle}
});
The data send would look something like {"title": "AC3"}
This AJAX request would go to the routes file which looks like this:
match '/gametitle' => 'loadtests#gametitle_post', via: :post
This route would then send it to the loadtest controllers gametitle_post method. Which looks like the following:
def gametitle_post
#gametitle = params[:title]
HTTParty.post("http://supersecret.com/loadtests",
:query => { :title => #gametitle })
render nothing: true
end
This is meant to receive the AJAX request, store the param sent, and then send a HTTParty request to receive JSON. But this is where I am stuck at the moment. Whenever I try to output the variable in #gametitle by console.log('<%= #gametitle %> it is an empty string.
Thank you for any help that you can give me in assisting me with this problem.
def gametitle_post
#gametitle = params[:title]
#some_variable = HTTParty.post("http://supersecret.com/loadtests",
:query => { :title => #gametitle })
//Access #some_variable in your view
return
end

Reading variable value from Rails controller in view for Rails

I have an instance variable, #source_code in my Rails controller that I want to retrieve in my Ajax response via the success function. I am calling this Ajax function from my index.html.erb file and it renders a show.html.erb file. I want to get my text area to print out the #source_code.code value.
SourcesController.rb
def show
Rails.logger.debug("REACHED: show >>")
#source_code = Source.find_by(id: params[:id])
Rails.logger.debug("REACHED: source_code >>" + #source_code.code.to_s)
#sources = Source.all
end
index.html.erb
function updateTextArea(source_id){
console.log(source_id);
$.ajax({
type: "GET",
url: "/sources/" + source_id,
data: {source_id: source_id},
success: function (response){
alert("Ajax success")
console.log("<%= #source_code %>");
editor.session.setValue("<%= #source_code %>");
},
error: function(){
alert("Ajax error!")
}
});
Expanding on Nycen's answer, you first want your controller handle the ajax request and return a JSON response:
def show
respond_to do |format|
format.json { render json: Source.find_by(id: params[:id]) }
end
end
PS: Take care with that, it will send all of the fields of your Source record down the wire. I call slice (see ActiveRecord.slice()) on the model to limit the fields returned in the JSON.
Then your JavaSript needs to use the JSON result of that ajax call:
function updateTextArea(source_id){
console.log(source_id);
$.ajax({
type: "GET",
url: "/sources/" + source_id,
success: function (response){
alert("Ajax success")
console.log(response.code);
editor.session.setValue(response.code);
},
error: function(){
alert("Ajax error!")
}
});
It depends on how your routes are setup, but there should be no need to set the data property in the Ajax call. Your route is likely to pull it from the URL path: /sources/12345.
Note there is no show.html.erb with this setup. There is no view, your controller just returns JSON.
You're expecting your success handler to have access to #source_code just like a "show.html.erb" view would, but it doesn't work that way.
When you use ajax, the method is called from the browser; it's a piece of code you send away from your server, it can still interact with it, but it doesn't have access to the controller variables.
So, your show action needs to render something your handler can understand, for instance json. Then you'll have access to it in your success by reading your "response" variable.

Selecting data from another page in Ajax

This is my ajax handling code:
$.ajax({
url: "shirts/first?page=" + params[:page],
type: "GET"
})
How to tell Ajax to take the results from the next page in the shirts/first file?
I wrote the code as I've shown but it throws a error saying 'syntax error'! How can I solve this?
Also my .js.erb file if its of some help:
$("#container1").append("<%= escape_javascript(render 'shirts/first')%>");
If you're performing ajax pagination, you'll have to ensure you can handle the Ajax request on the controller (using respond_to), and send the correct data:
JS
#app/assets/javascripts/application.js
$("a.pages").on("click", function() {
$.ajax({
url: "shirts/first?page=" + $(this).attr("id"),
type: "GET"
});
});
You'd need to have your pagination buttons with the page's ID for this
Controller
#app/controllers/shirts_controller.rb
def first
#shirts = Shirt.where(your_query)
respond_to do |format|
format.html
format.js
end
end
View
#app/views/shirts/first.js.erb
$("#container1").append("<%= raw(escape_javascript(render 'shirts/first')) %>");
you have mixed the rails params and javascript code, in javascript
url: "shirts/first?page=" + params[:page]
has syntax error because of : charachter, and even if you remove it means you have a javascript object named params and page is a variable which refers to a key in the params object, whereas here params[:page] refers to a querystring which its key is page in the current request from the client.
So change it like:
$.ajax({
url: "shirts/first?page=<%= params[:page] %>",
type: "GET"
});
You have to be careful here, cause the code above means the current page is being loaded with the page in its querystrings like: http://example.com/homepage?page=helloworld and helloworld probably is the other page in your story.
and for your .js.erb file, in rails 3.0.8, you have to wrap every escape_javascript call with raw():
$("#container1").append("<%= raw(escape_javascript(render 'shirts/first')) %>");

How to call action on onclick-javascript in ruby on rails

I want to perform an action do file in controllers/static_pages_controller.rb:
def fileopen
my_file = File.new("public/CHNAME1.txt","w")
my_file.write "\tfasf"
my_file.close
end
(it work well when i define it in helper and call it in view.)
in myview.html.erb, i want some thing like <button id="button" onclick="readfile()" />
How can I do that?
I tried in application.js
function readfile() {
alert('readfile work')
$.ajax({
alert('ajax work')
url: "/fileopen",
type: "POST",
##don't know what to do to make fileopen work
}
});
}
routes.rb
match '/fileopen', to:'static_pages#fileopen', via: 'get'
and it's seem nothing happen. Only the first alert work.
In answer to your question directly, you have to be able to handle the JS request in the controller. This is typically done by using the respond_to block in Rails, like this:
def fileopen
respond_to do |format|
format.js {
my_file = File.new("public/CHNAME1.txt","w")
my_file.write "\tfasf"
my_file.close
}
end
end
This code may give you some sort of a response with your current code, but it might be the case that you need to appreciate better how Ajax & Rails work in order to help you better
How Ajax Works
Ajax is a javascript technology which sends an "asynchronous" request to other pages on your website. By their nature, asynchronous requests are done completely independently of your main HTTP request, and basically act like a "pseudo" browser -- working in the background
Ajax is used to pull data from JS-enabled endpoints (which are handled with the respond_to function in Rails, which you can then use to modify your page in some way. A lot of people get confused with Ajax, but it's actually quite simple -- it's just javascript which pulls data from another page, allowing you to manipulate your page with that data
Using Ajax In Your Views
The reason why this is important for you is because you mentioned you didn't know what to do with the success callback of your app. Hopefully my explanation will show you that the success part of the $.ajax call should be used to append the data you receive from the controller on your page
This can be done in this way:
$("#button").click(function() {
$.ajax({
url: "/static_pages/fileopen",
type: "POST",
data: {name: $(this).val()},
success: function (data) {
// append data to your page
$("page_element").html(data);
}
});
});

Categories