AJAX (Asynchronous Javascript — with Rails applications)

Saman Batool
5 min readSep 27, 2022

In a standard HTTP request-response cycle, we make a request from the browser - it hits our server - we receive the information we need and it is sent through a new page (causing a page refresh for every cycle). However, sometimes even while the whole page is reloaded, only a specific part is actually being updated and everything else (such as the page title or navigation bar, for example) stays the same. This is definitely a hit — not just on performance but resources as well — to continue to reload the page when there could be better options.

One such option is submitting a form as an AJAX request instead of a regular HTTP submission. AJAX stands for Asynchronous Javascript and it is basically called an XHR request (or an XML HTTP request). A quick google search defines an XHR request to be able to retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing. This essentially means that all you have to do is submit your form via AJAX, the request will be received by your server and without reloading anything else just update the part of your page that needs to be altered based on the form submission with some Javascript.

Use AJAX for form submission

  1. Navigate to the view file, where the information is currently being served. Most likely you have a div iterating through the submission and displaying certain attributes. Since our intent is just to load this part and leave the rest of the page as is, you can move this section of code to a partial.
  2. Create a partial under the correct folder and provide an applicable name that helps to understand what this section is displaying. For understanding purposes, let’s call this ‘_results.html.erb’ (the ‘_’ signifies a partial file). Copy over your code to this file and render the file correctly in your original view page:

    <%= render result %>

    NOTE: if your partial is located in a specific folder, make sure to add that in your path while rendering. For example, if you placed it under a ‘users’ folder, you would render <%= render user/result %>
  3. You can do a quick test now to see if everything is being submitted correctly and rendering the same way as it was before.
  4. If you pull up the development tools in the browser and inspect your form, you will see the usual form action, method, etc. To submit this form via AJAX, you would need to set the attribute remote: true in your form tag.

<%= form_tag search_stock_path, remote: true, method: :get do %>

<% end %>

Adding this will turn the form submission into an AJAX request. After these changes, if you inspect the same form, you will see a data-remote=“true” attribute displaying within the form tag. This means that the application now knows that this is an AJAX request and is no longer just an HTTP request.

Now if your try to submit your form, you will initially see that nothing is changing in your view. This is because you are submitting the form via ajax but are not handling the Javascript request anywhere in the app (as of now). If you pull up the network view in your dev tools — you will see that the update has happened, the server has received the request and there was a response — you are just not able to see it in the browser. To do this, we need to use some javascript to render the result partial in our view page.

Setup Javascript response

  1. First, you need to identify the specific part of your view page (currently we are rendering the partial file there). You can easily do this by creating a div.

    <div id=“results”>
    REMOVE RENDER
    </div>


    You can remove the render file line now, you won’t be needing it anymore.
  2. We need to respond to the request that we are getting at the server side with javascript. Navigate to your controller action that handles the submission of your form and add a response where you have a valid submission:

    def search

    if @stock
    respond_to do |format|
    format.js { render partial: ‘result’ }
    end

    end

    This is going to expect a js.erb file names result. Create a file, right where you initially created your results partial, and name it as ‘_result.js.erb’. Also if you were rendering a path/URL after successful submission in your controller, you can go ahead and remove that (you will not be re-rendering a URL).
  3. You can do a simple test here to make sure everything is working properly by adding an:

    alert(“Hello world!”)

    to your result js file and see if it shows upon form submission. Hopefully, this is working correctly. Now all you have to do is simply render your initial partial file here instead of the alert code you added for testing.
  4. To render the file properly, you can first grab the div that you created in your view page (in our case id=“results”) with querySelector in your js file:

    document.querySelector(‘#results’).innerHTML = ‘<%= j render ‘result.html’ %>’

    j here is an alias for the escape_javascript method to signify ruby code in your JS file. So writing it like this will work as well:

    document.querySelector(‘#results’).innerHTML = ‘<%= escape_javascript(render ‘result.html’) %>
  5. Now if you submit your form in the browser, your partial file should be rendering properly! You will also notice that the URL isn’t changing like it was before with each submission. Only a specific part of the page is being updated.

Now that you have your form submission working with ajax for valid submissions, you can use the same partial to render for invalid searches and other use cases associated with the same form. To do this, you will simply respond with js as you did before in your controller under the instances:

respond_to do |format|

flash[:alert] = “Please ender a valid symbol to search”
format.js { render partial: ‘result’ }

end
// you can remove any redirect or render you have here also

In this case, we are rendering flash messages. To enable the user to see these massages in the view, you will simply add it to your results partial file. This way you are directing the controller to your partial and the partial file will display the adequate flash message/styling. Note that if you are displaying flash messages to handle invalid searches like this example, these messages persist for one HTTP cycle (this is the nature of flash messages in rails). Because we are using ajax for form submission, there is no reload for the page and so it is possible that the messages stay there while you submit the form again. You can avoid this by simply changing:

flash[:alert]

to

flash.now

Flash.now avoids the requirement of persisting for one cycle.

At this point all of your functionality associated with using AJAX and XHR requests to submit your form remotely, so that you don’t have to reload the page should be working.

--

--

Saman Batool

Software engineer navigating through problems in Rails and React. I like sharing my thinking processes, solutions and project learnings. I’m based in LI, NY.