Using AJAX POST from javascript to Rails 4 controller with Strong parameter - javascript

I'm newbie with Rails
My purpose is insert song_id and title which received from Javascript via AJAX POST into Database (MySQL)
In my javascript file
var song_id = "23f4";
var title = "test";
$( document ).ready( function() {
jQuery.ajax({
url: 'create',
data: "song_id=" + song_id + "&title=" + title,
type: "POST",
success: function(data) {
alert("Successful");
},
failure: function() {
alert("Unsuccessful");
}
});
} );
In my editor_controller.rb
class EditorController < ApplicationController
def new
#song = Song.new
end
def create
logger.debug("#{params[:song_id]}")
logger.debug("#{params[:title]}")
#song = Song.new(song_params)
if #song.save
redirect_to root_path
else
flash[:notice_song_failed] = true
redirect_to root_path
end
end
private
def song_params
params.require(:song).permit(:song_id, :title)
end
The problem is when I running the Rails app with this code, the Console notices me that
ActionController::ParameterMissing at /editor/create
param is missing or the value is empty: song
I'm trying to use
private
def song_params
params.require(:song).permit(params[:song_id], params[:title])
end
but it doesn't work and notices me the same, moreover in the terminal log told me below
Started POST "/editor/create" for ::1 at 2015-04-01 01:07:23 +0700
Processing by EditorController#create as /
Parameters: {"song_id"=>"23f4", "title"=>"test"}
23f4
test
Completed 400 Bad Request in 1ms
Do I missed something in my code, Thanks for Advance.

You are not sending a song parameter at all. It looks like you need to update the data line in the jQuery.ajax call to include the song parameter like so:
data: {song: {song_id: song_id, title: title}}

This:
params.require(:song).permit(params[:song_id], params[:title])
is saying "require the 'song' parameter, and allow 'song_id' and 'title' through. If you don't pass a song parameter, you'll get a bad request.
You can either:
Change that line of code to remove the require on 'song'
or
Like #infused says, change your ajax call to send a song JSON object.

Related

How to send post request to rails action

I'm new to rails so I don't know if that is the best practice. I'm trying to send user input from index view to the index action using ajax then update the view with user input. I'm not trying to save this input in the database.
The #url always return nil.
NOTE: I try to create a custom action with no luck because it requires a template.
Thanks in advance :)
The index action
def index
#url = params[:option]
end
The index view
<input type="text" id="exampleFormControlInput1">
<p id="resp-result"><%= #url %></p>
<script type="text/javascript">
$(".button").click(function(event){
var userinput = document.getElementById("form").value;
console.log(userinput);
event.preventDefault();
$.ajax({
url:"/responses/",
type: "POST",
data: {option: userinput},
dataType: "text",
success:function(result){
alert("success" + result);
},
error:function(result){
alert("error" + result);
}
});
});
</script>
Yuna you will need to output response in json. lets assume that your ajax script can send data to ruby on rails backend properly.
Try this
at ajax
not this
url:"/responses/",
but
url:"/responses.json",
you can then get result as per
alert("success" + result.myurl);
you can myurl as part of the json response
Finally try this
def index
respond_to do |format|
##url = params[:option]
#url='nancy more url'
format.json do
render json: {myurl: #url}.to_json
end
end
end

Action Cable notifications for multiple subscriptions

I'm trying to get a little red notifications circle to update dynamically in my Rails chat application using Action Cable. The problem is that sometimes when a message is sent, it seems to trigger the receive function more than once. I'm pretty sure I have the subscriptions defined correctly, but something is going wrong.
Here I make sure to create the subscriptions using the chat_id parameter. The same parameter is used in the submitNewMessage function
assets/javascript/channels/chat.js
$(document).on('turbolinks:load', function() {
submitNewMessage();
$.ajax({
type: "GET",
dataType: "json",
url: "/chats",
success: function(data){
$.each(data, function(i, chat){
App['chat' + chat.id] = App.cable.subscriptions.create({
channel: "ChatChannel",
chat_id: chat.id},
{ received: function(data){
# Code to update notifications
}}
});
}
}
});
function submitNewMessage(){
$('#message_text').keydown(function(event) {
if (event.keyCode == 13) {
var text = event.target.value
App['chat' + chat_id].send({text: text})
$('#message_text').val(" ")
return false;
}
});
}
});
And in the subscribed method I also use the chat_id params
channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat_#{param['chat_id']}_channel"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def receive(payload)
Message.create(user_id: current_user.id, chat_id: params["chat_id"], text: payload["text"])
end
end
How could the received function in chat.js be triggered more than once when a new comment is triggered?
Turns out that the Ajax request was creating a double of each request, when I visited other pages. I fixed it by adding
if (App['chat' + chat.id] == undefined){...
before creating the subscriptions. This way it only creates a subscription if it doesn't already exist.

Rails trouble sending AJAX data to controller

I'm a AJAX rookie, so bear with me. I'm trying to send data from a chat-message box to two places -- the actual chat box and to a rails method. That way I can display the meesage, and also store the message in my DB.
I have the following JS/HTML code
<button onclick="myFunction()" name="submitmsg" type="submit" id="submitmsg" value="Send">Try it</button>
<script>
function myFunction() {
var x = document.getElementById("frm1");
console.log(x);
var text = "";
var i;
for (i = 0; i < x.length ;i++) {
text += x.elements[i].value + "<br>";
}
document.getElementById("chatbox").innerHTML += text;
$.ajax({
url : "/messages/create",
type : "post",
data : { data_value: x }
dataType : "text" //this might be wrong?
});
}
</script>
I can successfully insert into the HTML DOM, but it isn't sending the data to the messages controller create action. My messages controllers is named messsages_controller.rb and the action is create.
I've added debugger in my create action in order to then view what params are, but it never even executes the code.
Some routes:
messages GET /messages(.:format) messages#index
POST /messages(.:format) messages#create
new_message GET /messages/new(.:format) messages#new
edit_message GET /messages/:id/edit(.:format) messages#edit
message GET /messages/:id(.:format) messages#show
PATCH /messages/:id(.:format) messages#update
PUT /messages/:id(.:format) messages#update
DELETE /messages/:id(.:format) messages#destroy
UPDATE
wait, something is wrong with my JS code. It was previously inserting HTML into the DOM, but somewhere along adjustments it stopped. Now the console is throwing the error new:110 Uncaught SyntaxError: Unexpected identifier line 110 is commented out.
When I the .ajax call out of the function, then it works fine. I have something syntactically wrong when I call the .ajax function inside myFunction()
$.ajax({
url : "/messages", //by rails convention doing a post simply to '/messages' should be handled by create action
method : "post",
data : { data_value: x },
dataType : "json", //this might be wrong?
success: function(response){
//do something,maybe notify user successfully posted their message
},
error: function(error){
console.log(error);
}
});
And in your create method you should handle json requests
def create
//save message
#message.save!
respond_to do |format|
format.json { json: #message.as_json }
end
end
This is how your code should look like. You can always do more creatively.
Please checkout this gist

Django + Ajax error in returning data

I have a model called Item and I'm trying to create Items with Ajax, everything looks to be working ok, but I'm getting and error at the end of the process, in the success function in Ajax. I have been reading a lot of answers to questions like this here in StackOverflow but I couldnt make it work:
This is my model:
PRIORITY_CHOICES = (
(1, 'Low'),
(2, 'Normal'),
(3, 'High'),
)
class Item(models.Model):
name = models.CharField(max_length=60)
description = models.TextField(max_length=1000)
created = models.DateTimeField(auto_now_add=True)
priority = models.IntegerField(choices=PRIORITY_CHOICES, default=1)
done = models.BooleanField(default=False)
meeting = models.ForeignKey(Meeting)
def __str__(self):
return self.name
This is my view, whichs is working Ok and saving the data into de database:
from .forms import AddItemForm
from .utils import render_to_json_response
class AjaxFormResponseMixin(object):
def form_invalid(self, form):
return render_to_json_response(form.errors, status=400)
def form_valid(self, form):
# save
self.object = form.save()
# initialize an empty context
context = {}
# return the context as json
return render_to_json_response(self.get_context_data(context))
class AjaxItemCreateView(AjaxFormResponseMixin, CreateView):
form_class = AddItemForm
def get_context_data(self, context):
context['success'] = True
context['name'] = self.object.name
context['description'] = self.object.description
return context
as you can see, I'm using a custom shortcut called render_to_json_response in order to parse data in Json
this is the code of the shortcut (Please notice that I'm printing the context, in order to verify the data):
from django.http import JsonResponse
def render_to_json_response(context, **response_kwargs):
print (context)
return JsonResponse(context)
(if you're wondering why I'm using this simple shortcut it's because previously I was trying to return the response with HttpResponse and specifying content_type="application/json", but it also wasn't working)
This is my ajax code:
function AddItem(event){
var csrftoken = getCookie('csrftoken');
var item_name = $('#item-name').val();
var item_desription = $('#item-description').val();
var item_priority = $('#item-priority').val();
var item_meeting_pk = $('#item-meeting-pk').val();
var url = "/item/add/";
$.ajax({
type: "POST",
url: url,
data: {
'name': item_name,
'description': item_desription,
'priority': item_priority,
'meeting': item_meeting_pk ,
'csrfmiddlewaretoken': csrftoken
},
success: function(data){
alert("success");
alert(data);
},
complete: function(data){
alert("completed");
alert(JSON.stringify(data));
}
});
}
and, finally, this is the form that calls the AddItem() function:
<form>
{% csrf_token %}
<input type="text" placeholder="Nombre del item" id='item-name'/>
<input type="text" placeholder="DescripciĆ³n del item" id='item-description'/>
<select id="item-priority" name="provider" class="form-control">
<option value="1">Baja</option>
<option value="2">Normal</option>
<option value="3">Alta</option>
</select>
<input type='hidden' id='item-meeting-pk' value='{{ meeting.pk }}'>
<button onclick='AddItem()' class="button-blue" >Agregar</button>
</form>
When I submit the form, everything goes fine, and in my django shell I can see that the post request is returning 200 and the data is printing ok:
{'name': 'asdkkasd', 'description': 'sdksdksjd', 'success': True}
[29/Aug/2015 08:34:22]"POST /item/add/ HTTP/1.1" 200 65
in the ajax function I have javascript alerts in both success and complete, but only the complete's one is executing and this is what I'm getting with the execution of alert(JSON.stringify(data));:
{"readyState": 0, "responseText":"", "status":0, "statusText": "error"}
I hope you can help me, thank you :)
Your form is almost certainly invalid; you're returning a 400 status in that case from form_invalid, which triggers jQuery to call the failure function if there is one, rather than success.
Unfortunately, you can't use proper RESTful status codes in this kind of situation. An invalid form submission should still return a 200.
There is a difference between success and complete function of the ajax function that you are using...
success
It gets called on a response of 200 (OK).
complete
This will get called always , well as the name suggests the request did succeed, even if was a failure on the server side or OK response. It just succeeded (ie: landed your server and brought something back to offer to your client(browser,mobile whatever).So that's complete method for.
You can do away with this method and can use only success if not needed otherwise.
For more info. Read here
FYI :
The readystate output you showed says 0 , hence the request isn't initialized.It should be 4 for the request to be complete.

Ajax does not receive data on second call

i am making a calendar, and i make an ajax request on page load to get the some data from the rails db.
the ajax call successfully receives object on page load.
when i click on next or previous button to get the previous months data or next months data, even though the ajax call happens, no data object is receiving on success callback
i receive a set of objects which i access like the code below but only for the page load ajax call, the ajax call gets a status code 200 - OK each time but no json object is received on next requests.
In other words, console.log(data) only works on the page load event while console.log($month) works everytime
UPDATE: using the dev tools, i can see the response data, but they are not accessible from success in ajax...
UPDATE 2: when i uncomment error i get the message "The error code is: OK"
my ajax code looks like this
function retrieve($month) {
console.log($month);
var jsondata = {
events: {
month: $month,
}
}
$.ajax({
cache: false,
type: "POST",
url: "/events/find",
data: jsondata,
dataType: json,
statusCode: {
200: function() {
//alert("200");
},
202: function() {
//alert("202");
}
},
success: function(data) {
//alert("Data Send!");
//var data = JSON.stringify(data);
console.log(data);
for (var i = 0; i < data.length; i++) {
var day = data[i].date.substring(0, 2);
$("td[data-day='" + day + "']").addClass('added');
}
},
error: function(xhr) {
//alert("The error code is: " + xhr.statusText);
}
});
}
events_controller
def find
params = event_params
#events = Event.where('date LIKE ?',"%#{params[:month]}%")
respond_to do |format|
if #events
format.json {
render json: #events.to_json
}
else
render 'index'
end
end
end
private
def event_params
params.require(:events).permit(:date, :timerange,:month)
end
example response from rails log
Started POST "/events/find" for ::1 at 2015-08-16 16:09:59 +0300
Processing by EventsController#find as */*
Parameters: {"events"=>{"month"=>"September"}}
Event Load (0.1ms) SELECT "events".* FROM "events" WHERE (date LIKE '%September%')
Completed 200 OK in 2ms (Views: 0.1ms | ActiveRecord: 0.1ms)
Just for future reference for someone who might need this.
The problem was the dataType: json
it seems that when rails converted the results to json, they were invalid for jquery thus the error event was fired.
removing dataType.json from the ajax request fixed my problems.

Categories

Resources