Passing a javascript variable (string) to the controller via ajax - 404 - javascript

I am trying to pass a javascript variable from my view to my controller via ajax according to the example shown here: Passing JavaScript variable to ruby-on-rails controller
my controller "pages_controller.rb" contains the following method:
def test_page
#message= params[:id]
puts #message
end
the respective view "test_page.html.erb" contains javascript with an ajax call which is triggered by clicking a button:
<button id="submit_button">Submit Text</button>
<script>
$("#submit_button").on('click',function(event) {
var string = "helloWorld";
$.ajax({
url: "/test/test_page/?id="+string,
type: "POST",
dataType: "text",
success: function(){
alert('Saved Successfully');
},
error:function(){
alert('Error');
}
});
});
</script>
In routes.rb I have defined the following route:
post 'test/test_page/:id', to: 'pages#test_page'
However, when I press the button I get the defined error-alert and upon inspecting the browser console I see the following error:
jquery.js:11007 POST https://my-website.com/test/test_page/?id=halloWelt 404 (Not Found)
But I can see that "rake routes" shows that the following route is defined:
POST /test/test_page/:id(.:format) pages#test_page
I have tried defining another method in the controller and rerouting, however the 404 error still remains. What can I do to fix this 404 error?

If you're looking to pass the :id to that route, you can use the following url: https://my-website.com/test/test_page/halloWelt. (i.e. "/test/test_page/" + string)
I believe in your AJAX, for a POST request, if you want to pass any other data you should explicitly pass in the data like below, rather than via url parameters.
$.ajax({
url: "/test/test_page/" + string,
type: "POST",
data: { hi: 'there' },
...

Related

How do I send data via an Ajax Query to a Controller and then open a new JSP page as the Controller's return type?

This is a simplified version of a problem I'm having. How do I send data to a Spring Boot Controller via an AJAX Query and then open a new JSP page? When I send data to the url in the AJAX Query to the matching URL in my controller class it seems to run the code within that method but not open the JSP (or return type).
For example if I were to send the following data from an Ajax Query
var hello = "Hello World!";
$.ajax({
type: "POST",
url: "/message1",
data: {
message: hello,
},
datatype: 'json'
});
}
To this method in my Controller class
#RequestMapping(value = "/message1", method = RequestMethod.POST)
public String MessageReceiver(#RequestParam("message")String message,
BindingResult bindingResult,
Model model) {
System.out.println(message);
return "NewPage";
}
"Hello" will print in the console but the JSP page NewPagewill fail to open and will prompt no errors?
Usually if I just call the url in the controller (for example /message1) via a href link, or button etc the NewPage JSP page will open. It seems that the AJAX query is missing something. Do I have to update the URL in the Ajax Query to something similar to /message1/NewPage (tried this, didn't work), or add something to the controller because the NewPage JSP page will not open.
Add the success callback function to your ajax like so:
$.ajax({
type: "POST",
url: "/message1",
data: {
message: hello,
},
datatype: 'json',
success: function(data){
if(data === "NewPage"){
//Open new page
}
}
});
}

AJAX Post request not sending values to Django View

I am trying to pass some data from the frontend to the backend of my site using AJAX. This is the post request view in my django views:
def post(self, request):
id_ = request.GET.get('teacherID', None)
print(id_)
args = {}
return JsonResponse(args)
This is the function I have in javascript. I know the correct value is being passed because the console.log(teacher_id) prints the right value.
function send(teacher_id){
console.log(teacher_id)
var url = window.location.pathname;
$.ajax({
method: "POST",
url: url,
data: {
'teacherID': teacher_id,
},
dataType: 'json',
success: function (data) {
//location.href = data.url;//<--Redirect on success
}
});
}
When the code is run, and the print statement in my view is run, regardless of what the teacher_id is, None is printed.
what is wrong with the code?
In your Django view the data is being retrieved using GET.get() while the AJAX request is sending it using method: "POST".
POST data can't be retrieved in the same way as GET data so you should either change the way the data is being send (by changing the method in the AJAX call to GET) or read it using the related POST methods.
You can visit this Stack Overflow question if you are doubting which method to use.

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.

AJAX Post to store JSON with Python and javascript

I have been having problems with getting AJAX to post JSON correctly. The application is intended to be hosted on Google App Engine. But what I have does not post data.
Python
mainPage = """
<html>
html is included in my python file.
</html>
"""
class JSONInterface(webapp2.RequestHandler):
def post(self):
name =self.request.get('name')
nickname =self.request.get('nickname')
callback = self.request.get('callback')
if len(name) > 0 and len(nickname) >0:
newmsg = Entry(name=name, nickname=nickname)
newmsg.put()
if len(name)>0:
self.response.out.write(getJSONMessages(callback))
else:
self.response.out.write("something didnt work")
def get(self):
callback = self.request.get('callback')
self.response.out.write(getJSONMessages(callback))
This handler is meant to handle the Ajax calls from the web app. I am unsure if I need javascript to be associated with my main page in order to do so, as I haven't found information on it yet with my searches.
Javascript
$(document).ready( function() {
$("#post").bind('click', function(event){
var name = $("#name").val();
var nickname = $("#nickname").val();
postData = {name: name, nickname: nickname, callback: "newMessage"};
$.ajax({
type: "POST",
url: "http://localhost:27080/json",
data: postData,
dataType: "json",
done: function() {
// Clear out the posted message...
$("#nickname").val('');
},
fail: function(e) {
confirm("Error", e.message);
}
});
// prevent default posting of form (since we're making an Ajax call)...
event.preventDefault();
});
The Javascript for the post
Can someone advise me on how I could resolve the problem I am having. Thanks for the time and help.
Did you ask the same question yesterday and then delete it? I swear I just answered the same question.
You're not sending your data as a JSON string. If you want to send as JSON, you need to encode data as a JSON string, or else you're just sending it as a query string.
data: JSON.stringify(postdata),
HOWERVER, your request handler is actually processing the request properly as query string instead of JSON, so you probably don't want to do that.
For starters, the ajax call is pretty close. The full path
"http:://localhost:27080/json"
is not necessary, the relative path will work, but that is not the problem.
Your callback, as it stands, will work as 'success':
success: function(response) {
alert(response);
// Clear out the posted message...
$("#nickname").val('');
}
However, this callback is being phased out in favor of other methods. 'Done' should be chained like so:
$.ajax({
type: "POST",
url: "/json",
data: postData,
dataType: "json"
}).done(function(data){
console.log(data);
});
Also, there might be problems on the server. If you use some logging, you will see that the data is indeed being sent to the server.
import json ## we'll get to this below
import logging
class JSONInterface(webapp2.RequestHandler):
def post(self):
name = self.request.get('name')
logging.info(name) ## will print the value of 'name'
Unless your python function getJSONMessages(callback) is returning a json object, your callback will not be called, even after you add the response parameter.
In your python code:
import json
import logging
class JSONInterface(webapp2.RequestHandler):
def post(self):
callback = self.request.get('callback')
logging.info(callback) # will print correctly
self.response.out.write(json.dumps(callback))
Using the json.dumps method encodes the passing object to json, which is what your ajax object is looking for.

How to get content type of a given url inside Javascript?

I want to know the content type of a given url input by the user inside my Javascript code. Actually, I have a drop-down list (html,csv,xls etc.) and I want to make it so when the user inputs an url, I want to detect the type of the content of the url and based on this type I want to set the value of my drop-down list (html,csv,xls etc.). I know, I can get the content type using Ruby like this :
require 'open-uri'
str = open('http://example.com')
str.content_type #=> "text/html"
or, also, I could use curl to get the content and then parse it to know the content type. But, I need to do this inside my Javascript code because of my need explained above. Any thought ?
EDIT_1 :
I tried this code in my javascript :
$("#wiki_form_url").change(function(){
$.ajax({
type: "GET",
url: "content.rb",
data: {
// input_url: $("#wiki_form_url").val()
},
dataType: "html"
}).done(function (data) {
// `data` contains the content-type
alert('Success !!!');
}).fail(function () {
alert("failed AJAX call");
});
});
I have a ruby script content.rb inside which I do :
require 'open-uri'
str = open('http://www.ofdp.org/benchmark_indices/25')
str.content_type
But, it does not seem to work. I am getting Ajax failure. May be it's because of url path of the script content.rb ? How should I specify a script path here ? (Relative or absolute)
The same origin policy prevents you from using client side JavaScript to directly discover information about arbitrary URIs (URIs you control are a different story).
You'll need to get that information with another technology, such as your server side Ruby.
You could do this by simply submitting a form to the server and returning a new webpage to the browser.
If you don't want to leave the page, then you can pass the data using Ajax. There are no shortage of Ajax tutorials out there, here is a good one from MDN.
Here's an example of an AJAX call:
$(document).ready(function () {
$("#button_check").on("click", function () {
$.ajax({
type: "GET",
url: "Your URL",
data: {
input_url: $("#textbox_id").val()
},
dataType: "html"
}).done(function (data) {
// `data` contains the content-type
alert(data);
}).fail(function () {
alert("failed AJAX call");
});
});
});
Where your HTML is something like:
<input type="text" id="textbox_id" />
<input type="button" id="button_check" value="Submit" />
And your Ruby code would be something like:
require 'open-uri'
class TestController < ApplicationController
def index
req = open(params[:input_url])
render :text => req.content_type
end
end
I have never used RoR before, so I have no idea if this is right or works in the slightest. But it's what I could quickly conjure up when scrambling through several tutorials. It's simply the concept you seem to be looking for. You'll need to figure out how to map a URL to this method, and then update the AJAX option url to use that.
So in the Javascript code - in the done method, that means the whole AJAX request was successful and the data variable should contain the result from the Ruby code req.content_type.
Atlast I could figure out the whole thing with the great help of #Ian. Here is my completed code : In javascript file :
$("#wiki_form_url").change(function () {
$.ajax({
type: "GET",
url: "/wiki_forms/content",
data: {
input_url: $("#wiki_form_url").val()
},
dataType: "text"
}).done(function (data) {
// `data` contains the content-type
alert('Success');
console.log(data);
// alert(data);
}).fail(function () {
alert("failed AJAX call");
});
});
Inside my wiki_forms controller I created a new method named content :
def content
req = open(params[:input_url])
render :text => req.content_type
end
Then added a new route in routes.rb file :
get "/wiki_forms/content" => 'wiki_forms#content'
and used /wiki_forms/content as the ajax request url. And, everything is working nicely now.

Categories