How to make AJAX calls in Rails 5.1
Tags: rails, ruby, react, javascript
Published: 2017-08-23 11:10:18

---
title: "How to make AJAX calls in Rails 5.1"
published: true
description: A short tutorial on how to make AJAX calls with rails-ujs, jQuery or axios
tags: rails, ruby, react, javascript
canonical_url: https://learnetto.com/blog/how-to-make-ajax-calls-in-rails-5-1
---
![](https://thepracticaldev.s3.amazonaws.com/i/0wdo3c4b6tqpotx3oy94.png)

_Originally published at [Learnetto.com](https://learnetto.com/blog/how-to-make-ajax-calls-in-rails-5-1)_.

Rails shipped without jQuery as a dependency for the first time with version 5.1\. Rails used to rely on jQuery forÂ [**Unobtrusive JavaScript**](http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript)Â features but now ships with its own libraryÂ [**rails-ujs**](https://github.com/rails/rails/tree/master/actionview/app/assets/javascripts)Â with the same features.  

One of the most common use cases for jQuery in Rails was making AJAX calls through forms and links. If you’re using Rails 5.1 for the first time, you might get confused about how to make AJAX calls, especially things like data formats and including CSRF tokens.  

So this little tutorial walks you through a few ways you can do so:  
**1\. Use rails-ujs (no jQuery)**  

A new Rails 5.1 app automatically includes the rails-ujs script in the app’s application.js file:  


```
//= require rails-ujs

```

If you don’t want to include it there and use it only selectively, say if you’re making a separate React frontend with Rails’s new webpacker support, then you can do use rails-ujs by installing it as a package:  

```
$ yarn add rails-ujs

```

And then import and start it in your JavaScript file:  

```javascript
import Rails from â€˜rails-ujs’
Rails.start()

```

Remove this line from application.js :  

```
//= require rails-ujs

```

Now let’s say we want to make an AJAX POST call to an API endpoint/things with some data which looks like this:  

```javascript
mydata = {
 thing: {
  field1: value1,
  field2: value2,
}}
```

Making an AJAX POST call with rails-ujs looks identical to making it with jQuery:  

```javascript
Rails.ajax({
  type: "POST", 
  url: "/things",
  data: mydata,
  success: function(repsonse){...},
  error: function(repsonse){...}
})
```

Except for one thing! As far as I can tell, you can’t simply send JSON data. So we need to convert mydata to application/x-www-form-urlencoded content type manually like this:  

```javascript
mydata = 'thing[field1]=value1&thing[field2]=value2'

```

jQuery does this conversion automatically before submitting a request.  

I assumed rails-ujs has some automatic way of doing it, but I couldn’t find anything in the docs orÂ [**code**](https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee).  

If you know,Â [**let me know**](https://stackoverflow.com/questions/45820587/how-do-you-send-json-data-in-a-rails-ujs-rails-ajax-post-call-not-using-jquery).  

rails-ujs automatically takes care of including the CSRF token with the request.  

**2\. Use jQuery**

If the manual data conversion puts you off, you can still use jQuery. You may be relying on jQuery for other things in your app anyway, so here are couple of ways of using jQuery with Rails for making AJAX calls:  

**2.1 Use the jquery-rails gem**

This gem used to be automatically included in previous versions of Rails. You can install it by adding it to your Gemfile:  

```
gem 'jquery-rails'

```

Then run:  

```
$ bundle install

```

And include jquery and jquery_ujs in your application.js file:  

```
//= require jquery
//= require jquery_ujs

```

That’s all you need. Now you can make your AJAX call in the usual way:  

```javascript
$.ajax({
  type: "POST", 
  url: "/things",
  data: mydata,
  success: function(data, textStatus, jqXHR){...},
  error: function(jqXHR, textStatus, errorThrown){...}
})
```

jquery_ujs takes care of including the CSRF token and jquery converts the data to application/x-www-form-urlencoded content type automatically.  

**2.2\. Use jquery package from npm**

If you don’t want to use a gemified version of jQuery, you can install it as a JavaScript package from npm:  

```
$ yarn add jquery
$ yarn add jquery-ujs

```

Then import them in your JavaScript file:  

```javascript
import $ from â€˜jquery’
import {} from â€˜jquery-ujs’

```

Make sure to remove the jquery-rails gem if you have it installed and remove jquery and jquery_ujs from application.js.Â   

You may get an error saying jQuery is not defined. In your webpack config file add this to the config.plugins array:  

```javascript
new webpack.ProvidePlugin({
 $: “jquery”,
 jQuery: “jquery”
}),
```

And now you will be able to use jQuery for making your AJAX calls.

**3\. Use axios**  

[**axios**](https://github.com/mzabriskie/axios)Â is a promise-based HTTP library. You can use it to make HTTP requests from node.js (on the server) and also AJAX requests from the browser.  

It’s a good alternative if you don’t need any of jQuery’s other features. To use axios in a Rails 5.1 app (with webpacker), install it:  

```
$ yarn add axios

```

Then import it in your JavaScript file:  

```javascript
import axios from â€˜axios’

```

Now we can make the AJAX call like this:  

```javascript
axios({
  method: 'POST', 
  url: '/things',
  data: mydata,
  headers: {
    'X-CSRF-Token': document.querySelector("meta[name=csrf-token]").content
  }
})
.then(function(response) {...},
.catch(function(error) {...}
})
```

A few things to note here:  

We have to include the CSRF token header. Unlike jquery_ujs and rails-ujs, it’s not automatically included with axios requests.  

We can specify it as a default setting to avoid repeating it in all our AJAX calls:  

```javascript
const csrfToken = document.querySelector("meta[name=csrf-token]").content 

axios.defaults.headers.common[â€˜X-CSRF-Token’] = csrfToken

```

We can access the success and error responses using the promises syntaxÂ _.then_.  

Another option is to useÂ [**fetch**](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), but it’s an experimental API and not available by default in all browsers. So you’re best off usingÂ [**Github’s polyfill library**](http://fetch). I prefer axios to fetch because fetch responses need to be first converted to json and the error handling can also be confusing.