Rails
axios

axiosをrailsと通信するときにとりあえずやっておくこと

環境

  • rails (5.2.0.rc1)
  • @rails/webpacker (3.2.1)
  • axios (0.17.1)

rails, axiosは導入済みとします

2018/3/2
systemテスト時にcsrf-tokenが取れなくてエラーになったのでaxiosのREADMEを眺めていたら
インスタンス作成時にオプションで指定すればいいだけだったのでそのように修正
csrf-tokenもない場合の考慮を入れました

2018/5/14
検索などgetでネストしたパラメータをaxiosで送ろうとしたら

axios.get('items', {
  params: {
    search: {word: "hoge"},
    page: 1
  }
})
Started GET "/items?search=%7B%22word%22:%22hoge%22%7D&page=1"
Parameters: {"search"=>"{\"word\":\"hoge\"}", "page"=>"1"}

上記のようにエスケープされてしまい params[:search][:word] が出来ませんでした
ということで、axiosはパラメータのパーサーを上書き出来るようなので下記を追加したところ

yarn add qs
import qs from 'qs'

const instance = axios.create({
  ...

  paramsSerializer: (params) => {
    return qs.stringify(params, {arrayFormat: 'brackets'})
  }
Started GET "/items?search%5Bword%5D=hoge&page=1"
Parameters: {"search"=>{"word"=>"hoge"}, "page"=>"1"}

良い感じになりました

成果物

app/javascript/packs/axios.js
import axios from 'axios'
import qs from 'qs'

const tokenElement = document.querySelector('meta[name=csrf-token]')
const instance = axios.create({
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
    'X-CSRF-TOKEN': (tokenElement) ? tokenElement.content : null
  },

  paramsSerializer: (params) => {
    return qs.stringify(params, {arrayFormat: 'brackets'})
  }
})

export default instance

一旦AxiosRootでオリジナルをインポートしてから、extendsした新しいAxiosクラスにhadersを定義するという感じです
後は拡張したファイルを使う場所でimportして使うだけです

app/javascript/packs/items.js
import Vue from 'vue/dist/vue.esm'
import axios from './axios'

export default {
  name: 'ItemList',

  props: {
    url: {
      type: String,
      required: true
    }
  },

  data () {
    return {
      items: []
    }
  },

  created () {
    this.asyncItems()
  },

  methods: {
    asyncItems () {
      axios.get(this.url).then(response => {
        this.items = response.data
      }).catch(error => {
        console.log(error)
      })
    }
  }
}

参照

https://github.com/axios/axios/issues/391
https://qiita.com/sukechansan/items/738b4bdaffc07c337a70