If I render json in Ruby, how do I access the values in javascript?
In ruby, if I write:
response = {:key => "val"}
response = response.to_json
render :json => response, :status => 200
How would I access "val" in javascript?
If I do alert(response) in javascript, I see a tag surrounding the json, does this make a difference or is this expected?
I tried jQuery.parseJSON(response) but I got a syntax error. If I try to access response directly, I don't get the correct value- should
response.key === "val"
evaluate to true?
Am I setting it up incorrectly in Ruby or accessing it incorrectly in javascript, or both?
It would really help if you could show your javascript code.
Anyway, one way you can do it is to use jQuery's ajax function and set the dataType to json.
$.ajax({
type: "GET",
url: "<your link>",
dataType: "json",
success: function(response) {
if (response.key)
alert(response.key);
});
});
Hope this helps.
Here's a quick example.
In ./config/routes.rb
match '/index' => 'application#index'
match '/json' => 'application#json'
The controller, ./app/controllers/application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery
def index
# server side code required by index
end
def json
response = {:key => "val"}
response = response.to_json
render :json => response, :status => 200
end
end
The erb page an ajax request is made from, in this case ./app/views/application/index.html.erb:
<script type="text/javascript" charset="utf-8">
$(document).ready(
function(){
$("a#my_ajax").bind("ajax:success",
function(evt, data, status, xhr){
console.log(data.key);
console.log(data.key === "val");
}).bind("ajax:error", function(evt, data, status, xhr){
console.log("doh!")
});
});
</script>
<%= link_to "test", {:controller=>"application", :action => 'json'}, :remote=> true, :id => "my_ajax" %>
Related
I have an ajax post to my backend rails app, it's to post a upload a file.
Post response with my files list in JSON
After that I need to reload my files list at view detalhes.html.erb page. This list is a partial. Here is what I have:
controller method:
def upload_arquivo
#ponto_venda = PontoVenda.find(params[:pv_id])
nome = params[:key].split('/').last
#arquivo = Arquivo.new(nome: nome, endereco: params[:url], s3_key: params[:key], tamanho: params[:tam], user_id: params[:u_id], tag_id: params[:tag])
if #arquivo.save!
ArquivoPontoVenda.create(arquivo_id: #arquivo.id, ponto_venda_id: #ponto_venda.id, fachada: false)
response = { files: filtro_pv_arquivos, message: "O arquivo '#{nome}' foi salvo" }
else
response = { files: '', message: 'Ocorreu um erro ao salvar o arquivo, por favor, tente novamente' }
end
render json: response
end
My ajax post method at _arquivos_upload.html.erb:
$.ajax({
url: 'some_url,
type: 'post', processData: false
})
.success(function(data) {
console.log(data.files.length);
// trying to reload partial after post request
$('#display-arquivos').html("<%= escape_javascript(render "arquivos_buscados") %>");
});
data.files are correct, I just need to find a way to pass this to my render partial. How can I do that? Or if this is a bad way to do it, how can I do better?
Here is where I render my partial detalhes.html.erb:
<div class="card" id="display-arquivos">
<%= render "arquivos_buscados" %>
</div>
I already have try a lot of this:
github link
set .html(data.files)
use js.erb file logic
That looks good. I'd suggest modifying your partial to accept a local variable and then explicitly passing it in when you render the partial.
<div class="card" id="display-arquivos">
<%= render "arquivos_buscados", locals { files: #files #add this } %>
</div>
$('#display-arquivos').html("<%= escape_javascript(render "arquivos_buscados", locals: { files : data.files } ) %>");
I think I would render back html instead of json. Then, in .success function of the ajax call, just do:
$.ajax({
url: 'some_url,
type: 'post', processData: false
})
.success(function(data) {
$('#display-arquivos').html(data);
});
You'll probably need to change your controller action along the lines of:
def upload_arquivo
...
if #arquivo.save!
ArquivoPontoVenda.create(arquivo_id: #arquivo.id, ponto_venda_id: #ponto_venda.id, fachada: false)
#files = #populate your #files variable
render "arquivos_buscados"
else
render :something_else
end
end
I have created different class-based views on Django. On the HTML i created some forms make a request with AJAX. My problem is that it gives me
Method Not Allowed (POST)
I don know if i'm doing it rigth, or if i need to modify something for it to work.
My view.py is something like this
class Landing(View):
def get(self,request):
if request.method == 'POST':
if request.is_ajax():
data = {"lat":20.586, "lon":-89.530}
print request.POST.get('value')
return JsonResponse(data)
return render(request,'landing.html',{'foo':'bar'})
And i send the reques from Javascript
$(document).ready(function() {
$('#productos').on('change', function(e) {
//Call the POST
e.preventDefault();
var csrftoken = getCookie('csrftoken');
var value = $('#productos').val();
$.ajax({
url: window.location.href,
type: "POST",
data: {
csrfmiddlewaretoken : csrftoken,
value : value
},
success : function(json) {
console.log(json);
drop(json);
},
error : function(xhr,errmsg,err){
console.log(xhr.status+": "+xhr.responseText)
}
});
});
});
I got some of the code from a web, but i really don't know how to use it, since they used it without class-based views.
So, What does need my code to accept the POST method?
The dispatch method of a class based view determines which function is called, so far you've written a get function, but no post function so just move the logic into a post function.
class Landing(View):
def post(self,request):
if request.is_ajax():
data = {"lat":20.586, "lon":-89.530}
print request.POST.get('value')
return JsonResponse(data)
def get(self, request):
return render(request,'landing.html',{'foo':'bar'})
I want to call a javascript function when click the submit button.I used form_tag , but the function did not get triggered.I want something like the following:
<%= form_tag show_table_job_plate_path, :onSubmit => 'start_form_request(); ' ,:onComplete => 'end_form_request();' ,:update => { :success => 'well_table_section' },:remote => true, method: :GET do %>
on submit is working but on complete is not working please help me?
There is no onComplete event on HTML Form. Check this
If you want to trigger something after on Ajax Call Complete. Use Ajax events like success, complete, error.
$("#yourform").bind('ajax:complete', function(data, status, xhr) {
//Your On Complete Code
});
Check this for all rails ajax events.
As you are using form_tag with remote:true, which means your rails server is going to send you response in JS format. So you can call your function with following two ways:
1) respond_to block: simplest and easy solution.
respond_to do |format|
format.js { render :js => "end_form_request();" }
end
2) js.erb file:
for your controller action you can have "action_name.js.erb" file, and in that file you can call you js function 'end_form_request()' directly.
Hope it helps you.
Updated:
action.js.erb
$("#well_table_section").html("<%= escape_javascript(render partial: 'well_table', :locals => { :params => #params } ) %>");
end_form_request("<%= #params %>");
You can try this
$("#your_form_id").on("ajax:success", function(xhr,data){
... //your complete function here.
})
As per your request I converted your requirement into Rails 4
This is form tag
<%= form_tag show_table_job_plate_path, remote: true, html: { onSubmit: 'start_form_request();', id: 'yourForm' } do %>
When you added the show_table_job_plate_path in the form you don't need to method: :GET
After the form you have to add this script.
<script>
$(document).ready(function(){
$('#yourForm').on('ajax:complete', function(e, data, status, xhr){
// Write onComplete Code
end_form_request();
}).on('ajax:success',function(e, xhr, status, error){
// Write onSuccess Code
well_table_section();
}).on('ajax:error',function(e, xhr, status, error){
// Write onError Code
});
});
</script>
following were my javascript where user post the updates:
$('.attachments-container').on('click', '.cover-attachment', function(event) {
var attachment_id = $(this).parent().find('input[name="product_attachment[id][]"]').val();
$.ajax({
type: "POST",
url: "/products/update_cover",
dataType: "json",
data: attachment_id,
complete: function(){
console.log('change completed');
}
});
event.preventDefault();
})
On my routes:
resources :products do
member do
match "update_cover", via: [:post]
post "update_cover" => 'products#update_cover'
end
end
On my controller:
class ProductsController < ApplicationController
skip_before_action :authenticate_user!, only: [:result, :show]
def update_cover
#attachment_id = params[:attachment_id]
render :json => {:status => 'success'}.to_json
end
end
I had no clue where this error comes from: ActionController::RoutingError (No route matches [POST] "/products/update_cover"): Thanks!!
If you run rake routes in your terminal you will see that you do not have a route for products/update_cover. You have - products/:id/update_cover. Since you have defined it as a member route, you need to pass the parent_id as part of the route. Try this
url: "/products/" + attachment_id + "update_cover",
And you dont need to pass attachment_id in the data hash.
Incidentally, the 2 routes you posted essentially do the same thing. You can lose
match "update_cover", via: [:post]
I am trying to get a JSON response from a get request. However, I am getting the following error: Uncaught SyntaxError: Unexpected token u. I know the rails route works because I do get the response loaded successfully in the Console.
The Ajax Response is supposed to start when the checkbox changes and is checked.
Why am I getting this error from the $.parseJSON?
Rails Controller
def providers
#providers = User.order("last_name ASC, first_name ASC, middle_name ASC").where("provider_flag = ? and inactive_flag = ? and del_flag = ?", true, false, false).select("id, CONCAT(IFNULL(last_name,''), ', ', IFNULL(first_name,''), IFNULL(middle_name,'')) AS full_name");
respond_to do |format|
format.json { render :json => { :providers => #providers.to_json}, :status => :ok }
# format.json { render :json => #providers.to_json }
end
end
Javascript
$('#provider_chk').change(function() {
if($(this).is(":checked")) {
$.ajax({
url: '<%= providers_schedule_index_path %>',
type: 'GET',
dataType: 'json',
data: {
authenticity_token: $('meta[name=csrf-token]').attr('content')
},
success: function(data) {
console.log('loaded successfully.');
var providers = $.parseJSON(data.responseText)['providers'];
providers_count = $(providers).size();
console.log(providers);
console.log(providers_count);
},
error: function(data) {
console.log("An error has occurred!")
}
});
} else {
$('#providers_results').empty();
}
});
JSON Response
providers: "[{"id":2,"full_name":"Test, User"}]"
Your JSON response should look more like this:
providers: [{"id":2,"full_name":"Test, User"}]
The outermost quotations marks aren't needed.
If you really need the outer quote marks, you need to escape the inner ones.
In $.ajax({}), add the property "async:false". parseJSON hasn't gotten that JSON yet - it's immediately trying to operate on undefined ("u") and throwing the error.
Remove to_json since you are already telling rails to return json
format.json { render :json => { :providers => #providers }, :status => :ok }