Asynchronous communication with ajax. Flow of processing explanation
Bài đăng này đã không được cập nhật trong 7 năm
WHAT
We will be doing asynchronous communication using ajax and post messages without screen transition. I did not understand the process flow of ajax and jbuilder very well and I had a lot of trouble in understanding, so i make this post for not to forget
WHY
Because I did not understand the process flow of ajax and jbuilder well, it took a long time to write the code. ※ If i made something wrong, please leave comment below!
Process flow
1. Send form
- _form.html.haml
= form_for [@group, @message], html: {class: 'msg_form'} do |f|
= f.hidden_field :user_id, value: "#{@message.user_id}"
= f.text_field :body, autofocus: true, placeholder: "type a message", class: "form__textfield"
= link_to "#" do
%i{class:"fa fa-picture-o"}
= f.submit "Submit", class: "form__submit"
- Routing
GET /groups/:group_id/messages(.:format) messages#index
POST /groups/:group_id/messages(.:format) messages#create
2. Stop form transmission event and go to js processing
$(function() {
// Omitted
$('.msg_form').on('submit', function(e) {
e.preventDefault();
// Here stops the submit event of the form
var api_url = window.location.pathname;
// Get the path while sending the request by ajax
var formdata = new FormData($(this).get(0));
// Get value entered in form as formdata object
// You can check the contents of formdata with the following code
// for(item of formdata) console.log(item);
// Using ajax, send a request in json format.
$.ajax({
url: api_url, // Request path. Here is '/ groups / 23 / messages'
type: 'POST', // HTTP method
data: formdata, // Send with request data
contentType: false, // This is the type of data included in the request ( It seems to be in the request header)
processData: false, // This means not to change the actual type of data included in the request
// It seems that the above two designations have to be done
// Reference : http://semooh.jp/jquery/api/ajax/jQuery.ajax/options/
dataType: 'json', //send a request in JSON format
})
// So far, Specification of ajax request.
// As the request is sent, the routing is read.
// (Following is omitted)
// The code indicates If its going well do this, if not do that
});
});
3. Controller Process
A request for '/groups/:group_id/messages(.:format)' was sent from ajax at 2 and HTTP method 'POST'. According to routing messages # create (in short, the create action of the messages controller is processed.)
- messages_controller.rb
class MessagesController < ApplicationController
def create
@message = Message.new(message_params) // generate Message instant
@message.user_id = current_user.id // Add user_id, group_id which can not be taken with params
@message.group = Group.find(params[:group_id]) // Associate Group with Message instance
if @message.save // If you can save the Message instance
respond_to do |format|
format.html {redirect_to group_messages_path(params[:group_id])}
// Redirect if request is in HTML format
// Although it should not be read by this application but i still write down here
format.json
// If the request is in JSON format, run jbuilder (for this time)
// In this application, format.json should be read.
end
else // If you can not save Message instant
flash[:notice] = "Please input the message"
redirect_to group_messages_path(params[:group_id])
end
end
private
def message_params
params.require(:message).permit(:body ,:image, :user_id).merge(group_id: params[:group_id])
end
end
4. jbuilder work flow
The request was read in JSON format by ajax, and the create action in messages_controller.rb
worked.
Respond_to follows the description of format.json, views/messages/create.json.jbuilder is read.
- create.json.jbuilder
json.name @message.user.name
json.body @message.body
json.image @message.image
json.group_id @message.group_id
json.user_id @message.group_id
json.time @message.created_at
About the json style data object sent by the request
@message.user.name
is value for the name key.
For the body key @message.body
In short, the contents of data is a hash of the JSON format as follows. By specifying .key, each value can be acquired.
Object {name: "yukihiro", body: "ooo", image: null, group_id: 23, user_id: 23…}
Since jbuilder processing is over, we go to the second half of ajax in message.js.
5. When the ajax request succeeds / fails
$(function() {
function new_message(message) {
var new_message = $('<div class="msg">' +
'<p class="msg__username">'+ message.name +'</p>' +
'<p class="msg__time">'+ message.time + '<p>' +
'<p class ="msg__passage">' + message.body +'</p>' +
'</div>');
return new_message;
}
$('.msg_form').on('submit', function(e) {
// Omitted
// I sent a request with this ajax just now
$.ajax({
url: api_url,
type: 'POST',
data: formdata,
contentType: false,
processData: false,
dataType: 'json',
})
// When ajax request is successful .done is read
.done(function(message){
console.log('success!'); // For debugging
console.log(message); // For debugging
var html = new_message(message); // This is added because of adding a message asynchronously
$('.msg').append(html); // Add to reality
// Add 'html' to the end of 'chat__content'
$('.form__textfield').val(''); //Empty text field
$('.form__submit').prop('disabled', false); //Activate the submit button
})
// If ajax request fails, .fail will be read
.fail(function(message){
console.log('error!');
});
All rights reserved