Asynchronous communication with ajax. Flow of processing explanation
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 Because I did not understand the process ...
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
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!
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!'); });