【vue.js】mountedでリロード時にapiを叩く処理でthisの取り扱いにハマった

mountedを使って画面読み込み時にapiから取得した値をreleasesオブジェクトにバインディングしたかったけど、thisのスコープを理解していないためハマった。

###成功例
キモは次の`.bind(this)`である。ここでbind関数を指定しない場合、mounted内のthisはwindowオブジェクトを参照してしまう。

```js:
this.releases = response.data;
          }.bind(this))
```

```html:index.html.erb

 <ul>
  <li class="content" v-for="(release, index) in releases" v-bind:key="release.id">
    <div class="subContent">
      <img class="content-image" v-bind:src="release.image" v-on:click="openModal(index)">
      <h3>{{release.title}}</h3>
      <h3>{{release.name}}</h3>

```
対応するvueは次の通り。


```index.js
document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    el: '#app',
    data: {
      releases:{}
    },
    mounted:function(){
        axios.get(`/api/releases`).then(function(response){
          console.log(response);
          for(let i = 0; i < response.data.length; i++) {
            response.data[i].showContent = false;
          }
          this.releases = response.data;
          }.bind(this))
          .catch(function(error) {
            console.log(error);
          });
    },
    methods:{
      openModal: function(index){
        //console.log(this.releases[index].showContent)
        this.releases[index].showContent = true
      },
      closeModal: function(index){
        this.releases[index].showContent = false
      }
      
    }
  })
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339446/cbdd2d66-f0e0-5619-6636-75862e67d014.png)


###失敗例

```index.js
document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    el: '#app',
    data: {
      releases:{}
    },
    mounted:function(){
        axios.get(`/api/releases`).then(function(response){
          console.log(response);
          for(let i = 0; i < response.data.length; i++) {
            response.data[i].showContent = false;
          }
          this.releases = response.data;
          })
          .catch(function(error) {
            console.log(error);
          });
    },
    methods:{
      openModal: function(index){
        //console.log(this.releases[index].showContent)
        this.releases[index].showContent = true
      },
      closeModal: function(index){
        this.releases[index].showContent = false
      }
      
    }
  })
})
```
typeerrorが出力される。この場合releasesオブジェクトにapiから取得した値をバインディングできていない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339446/e3af888a-662c-bf4a-eba5-9ebde0435988.png)

##なんで

次の箇所でコールバックさせているのがダメっぽい

```js:
mounted:function(){
        axios.get(`/api/releases`).then(function(response){
          console.log(response);
          for(let i = 0; i < response.data.length; i++) {

```

[JavaScript中級者への道【2. 4種類のthis】](https://qiita.com/matsuby/items/36ac4743d5eed2391116)
>hoge関数の引数のcallbackがコールバック関数と呼ばれるものです。
ここで、以下のような形でオブジェクトのメソッドを渡すと失敗します。
>
```js
// 名前と、それを表示するメソッドを持つオブジェクトを作成する
var obj = {
  name : 'matsuby',
  sayName : function () {
    console.log(this.name);
  }
};

>// コールバック関数にメソッドを渡すと…
hoge(obj.sayName);  // => undefined
```
いつの間にかthisがグローバルオブジェクトを指しているというパターンです。
そこでbind()を使ってthisを任意のオブジェクトに束縛することで解決出来ます。

[JavaScript の超便利なメソッド bind で this を制御する](https://foreignkey.toyao.net/archives/763)
などを読んで対処

thisのスコープには気をつけようね、ということ