okay, I'm sure this is simple but I'm running out of hair to pull out. I'm posting a ajax request to my controller and trying to get the response in CoffeeScript. I tried moving to pure JS, but didn't make a difference.
the jQuery document implies that my newImage() should be newImage(data) but if i do that i get the error data undefined. With this code i just get undefined for my alert.
jQuery ->
$('select[data-type=scene]').change ->
i_num= $(this).attr('data-num').toString()
i_value= $(this).find(':selected').text()
request= 'new image for :'+ i_num + ': get :' + i_value + ': image'
$.post('/new_image', {request: => request}, newImage())
newImage= (new_url) ->
alert new_url
the controller is providing a response that i can see in the console, but the ajax callback doesn't seem to grab it.
the controller code is .
def new_image
request= params['request'].split(':')
#url= get_thumb_url(request[3])
#img_num= request[1]
reply= #img_num + '::' + #url
render json: reply, content_type: 'text/json'
end
the response is
3::https://bnacreations.s3.amazonaws.com/g/thumbnails/image.jpg
any suggestions of where i'm off track?
This calls the newImage function while building the argument list for $.post:
$.post('/new_image', {request: => request}, newImage())
# --------------------------------- function call --^^
If you only want to give $.post a reference to a function (which is what you want to do), then leave off the parentheses. Also, $.post just wants some data in the second argument whereas request: => request has a function as the value for request. You probably want this instead:
$.post('/new_image', { request: request }, newImage)
The => (fat-arrow) in CoffeeScript is for defining a bound function, it isn't a Ruby-style hashrocket for building hashes.
BTW, CoffeeScript has Ruby-ish string interpolation so you can say:
request = "new image for :#{i_num}: get :#{i_value}: image"
Related
I'm working on a tournament bracket based on the GOjs library, The bracket has score input.
Once my user is done editing the bracket I save the bracket into a JSON variable :
function save() {
var tojs = myDiagram.model.toJSON();
var payload = JSON.parse(tojs);
stringify_tojs = JSON.stringify(payload);
myDiagram.isModified = false;
I use XMLHttpRequest to able to post the payload into my rails model that handles 'payload' :
var request = new XMLHttpRequest();
request.onload = callback;
request.open("post", "http://localhost:3000/malesingles");
request.setRequestHeader("Content-Type", "application/json");
request.send(payload);
I don't know where I went wrong but I'm certain it's around my
controller params but I can't find my mistake already been a week, the
controller looks something like this :
#tournoi = Tournoi.new(bracket_params)
if #tournoi.save
redirect_to root_url
flash[:success] = "Your tournament bracket has been validated!"
# redirect_to #tournoi
else
render 'new'
end
end
I have included the bracket_params in private settings
def bracket_params
params.require(:tournoi).permit(:payload)
end
Tried different method to post the payload none really work, would appreciate some help to understand where I went wrong, I get a param is missing or empty :/.
#DezzH check out my latest commits from my repo https://github.com/fabriziobertoglio1987/sprachspiel/tree/feature/purchase-system I just built something like that using coffescript.. the commits include description of my work
basically what I figured out is, post request do not pass the parameters in the url so it is not easy to find them in the request, but you can check in your network tab
as you can see from the image I am passing
createPurchase: ->
$.ajax
url: "/products"
method: "POST"
dataType: "json"
data: { items: {product_id: '1', name: 'test' }}
error: (jqXHR, textStatus, errorThrown) ->
console.log "AJAX Error: #{textStatus}"
success: (data, textStatus, jqXHR) ->
console.log "Successful AJAX call: #{data}"
console.log data
then I set just a binding.pry in the controller and I can see my params there
I have rails controller:
class TrafficVolumeController < ApplicationController
def test
render json: Traffic.all
end
end
I can see it returns json:
On this AJAX request:
$.ajax '/traffic_volume/test',
type: 'GET'
dataType: 'json'
json: true
success: (data, textStatus, jqXHR) ->
$('body').append "Successful AJAX call: #{data}"
But data is of Anything type and in browser I can see:
So the question is how to work with this data parameter. Do I have to cast it to other type or I need to change HTTP headers in request or something in rails controller. Really need your help as I've spent so many time on this already. Thanks!
What you observe on the page, is the default string representation of object, which is not very helpful.
Try this one, should be much better:
console.log "Successful AJAX call: ", data
That data of yours, it's an array, right? If so, this should work as well
$('body').append(data[0].year) # or whatever you were going to do
# in the first place
I've rewritten my question to be more accurate. I have a bankaccounts controller / model.
I have the following method on my controller
def search
##ledgeritems = Ledgeritem.where("bankaccount_id = ? and transactiondate >= ? and transactiondate < ?", params[:bankaccount_id], params[:startdate], params[:enddate])
#bankaccount = Bankaccount.find(params[:bankaccount_id])
respond_to do |format|
format.js { render :partial => "bankaccount/bankledger" }
end
end
I've made two attempts to call this.
Attempt 1
Route for attempt 1
resources :bankaccounts do
post "search"
end
This shows the following route when I do a rake
bankaccount_search POST /bankaccounts/:bankaccount_id/search(.:format) bankaccounts#search
Javascript for calling attempt 1
$.ajax({
type: "POST",
url: "/bankaccounts/" + bank_account_id + "/search.js",
data: $('#edit_bankaccount_' + bank_account_id).serialize(),
success: function (result, status) {
$('#bank_ledger_div').html(result);
}
});
This calls the correct route on my controller, but the server sees it as a PUT instead of a POST and returns a 404.
Attempt 2
Route for attempt 2
resources :bankaccounts do
collection do
post "search"
end
end
This shows the following route when I do a rake
search_bankaccounts POST /bankaccounts/search(.:format) bankaccounts#search
Javascript for calling attempt 2
$.ajax({
type: "POST",
url: "/bankaccounts/search.js",
data: $('#edit_bankaccount_' + bank_account_id).serialize(),
success: function (result, status) {
$('#bank_ledger_div').html(result);
}
});
This calls the update route but still showing as a PUT command. In Firebug I see a 500 error with the following result
Couldn't find Bankaccount with id=search
Usually this error means you're making a GET request instead of a POST request.
For example:
GET /bankaccounts/search is assumed to be requesting the SHOW page for a bankaccount with ID = search
While
POST /bankaccounts/search would correctly hit your action.
Edit:
resources :bankaccounts do
collection do
post "search"
end
end
Is correct as well. Now I'm noticing that you are doing this to get your data:
data: $('#edit_bankaccount_' + bank_account_id).serialize()
that form likely has a hidden field in it, put there by rails, with name='_method' and value='PUT'. That is what is convincing rails that your POST is really a PUT. You'll need to remove that from the serialized data in order to correctly post the form.
If you want the /search url to be used without specifying an id, you should declare it as a collection action :
resources :bankaccounts do
collection do
post "search"
end
end
You can check the routes defined in your app with the rake routes command, to ensure that you defined what you meant.
The URL is expecting the format
/bankaccounts/:bankaccount_id/search
Is the error coming from this method? Could /bankaccounts/search be matching another route?
I have a simple scenario where I want to request a page. The request format is text/html. If there is some error in the controller/action logic for that request, I want to get an error message. The twist is that I want this error message to be communicated to be with a javascript response type (i.e. no page refresh). If there are no errors, then I want the page to be loaded via the expected text/html response type.
Basically, I want two different response types depending on whether there is an error or not. Is this doable in rails 3? If so, what is best practice?
A quick code sample would be much appreciated.
Thanks.
Sure it's doable!
I would do it like this:
def some_action
# code
# more code
# implicit or explicit rendering of an html template
rescue Exception => ex
render :json => ex.to_json,
:content_type => 'application/json',
:layout => false
end
i'm trying to render a json string in response to a request like following:
def check_progress
if request.xhr?
render :json=>"{'bytes_expected': #{session[:size]}, 'bytes_recieved': #{session[:size]}, 'last_seq': 0}".to_json
end
end
but in my js code :
$.getScript('contacts/check_progress', function(data){
console.log(data.bytes_recieved)
console.log(data.bytes_expected)
d.renderProgress(data);
});
I get undefined in response to data.bytes_recieved and data.bytes_expected.
what's wrong in my rails code?
I Think your main problem might be that your returning a string which looks like json and is not actually a json hash.
in your render statement you are hand formatting the json as a string... which is fine until you call to_json on it.
to_json is suspose to be passed a hash not a string.
You could try removing the .to_json at the end of your render statement:
render :json=>"{'bytes_expected': #{session[:size]}, 'bytes_recieved': #{session[:size]}, 'last_seq': 0}"
or create a ruby hash then convert it to json:
#ruby_hash = {
:bytes_expected => session[:size],
:bytes_recieved => session[:size],
:last_seq => 0
}
render :json=> #ruby_hash.to_json
The $.getScript method of jQuery inserts a <script> node to the <head> of your HTML document.
With that method your browser won't send the X-Requested-With HTTP header to the server. Because it will be a simple HTTP request not an AJAX one. And your browser is waiting a javascript in the response not a JSON data.
In the jQuery documentation of the $.getScript method is somewhat misleading because it says data in the callback function of the method signature, but it won't give you any data in the callback function, because your browser simply executes the javascript there is no actual payload with this request.
There is to possible solutions:
If you need to load data from cross-domain, then try to remove the request.xhr? condition an use JSONP method and callback
if it's not a cross-domain situation, simply load with a $.getJSON response and don't touch the condition
Update: and I have not seen it but #Barlow pointed it out you need to fix your json generation code in your rails app as he says.
You can simplify your code to:
def check_progress
if request.xhr?
render :json => {'bytes_expected' => session[:size],
'bytes_recieved' => session[:size],
'last_seq' => 0}
end
end
as render :json will do the conversion of hash into JSON object for you. I dont know if this will solve the problem.