Laravel + Vue.js + axiosで非同期postリクエストを送ろうとし時のハマったポイント(全部うっかりミス)をまとめた

タイトルと記事をフォームに入力してサーバーに送信してDBに登録する簡単な処理をaxiosを使って実現しようとした時にうっかりミス連発でちょっと時間がかかったのでミスったポイントをまとめときます。

##■前提
・Laravel5.4
・Vue.js2.x
・axios

##■最終的なソースコード
API側

```php
// routes/api.php
Route::group(['middleware' => 'api'],function(){
	Route::post('/article/{id}',function($id){
		$user = App\User::where('id',$id)->first();

		$article = new App\Article();
		$article->title = request('title');
		$article->content = request('content');

		$user->articles()->save($article);

		return ['title' => request('title'),'content' => request('content')];
	});

});

```

Vueコンポーネント側

```html
<!--resources/assets/js/components/Articles/Create.vue-->
<template>
	<div>
	    <div>
            <h4>記事投稿</h4>
            <div>
                <input v-model="title" type="text" name="title" placeholder="タイトル">
                <textarea v-model="content" class="form-control" rows="4" placeholder="コンテンツ"></textarea>
                <p>{{ title }}</p>
                <p>{{ content }}</p>
                <button v-on:click="postArticle">投稿</button>
            </div>
	    </div>
    </div>
</template>

<script>
    export default {
    	// メソッドの実行
        // created() {
        // },
        // メソッドで使う&テンプレート内で使う変数を定義
        data() {
            return {
                title:'',
                content:''
            }
        },
        // (読み込み時に)実行するメソッド
        methods: {
            postArticle(){
                var article = {
                    'title': this.title,
                    'content': this.content
                };
                var id = 1;
                axios.post('/api/article/' + id,article).then(res => {
                    console.log(res.data.title);
                    console.log(res.data.content);
                });
            }

        }
    }
</script>
```

##■ミスったポイント

###①パスにapiをつけ忘れ
処理をapi.phpに記述している時は、axiosのパスにapiを設定しないといけないのですが、それをつけ忘れてました。

```javascript
// Create.vue
axios.post('/api/article/' + id,article).then(res => {
  console.log(res.data.title);
  console.log(res.data.content);
});
```

###②v-modelでデータを取得する際の記述間違い
例えばv-modelで```title```と```content```を設定した場合、入力されたデータを```methods```で使うには、以下のように```this```をつける。

```javascript
methods: {
   postArticle(){
     var article = {
       'title': this.title,
       'content': this.content
     };
  }
```
※テンプレート内で使う場合は```this```をつける必要はない

```html
<p>{{ title }}</p>
```
いづれにしても```data()```で変数を宣言しておく必要がある。

```javascript
data(){
  return {
    title:'',
    content:''
  }
}
```

###③Articleモデル、Userモデルへのメソッドの定義忘れ

Userモデルにメソッドを定義してなくて、api.phpでの処理が完結しなかった。

```php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function articles()
    {
        return $this->hasMany(Article::class);
    }
}
```

##■非同期処理のエラーの確認方法

非同期処理の場合、api側でのエラーがページに表示されないしconsoleにはjavascript側のエラーしか出ないため、エラーの詳細が確認出来ないなぁ〜と悩んでいたが、GoogleChromeのデベロッパーツールでスタックトレースが見れる場所を見つけて助かりました。

その場所は、
ElementsやConsoleと並んでいる「Network」という部分。
その中の「Name」というパネル内に赤く表示されている部分がエラーが発生している部分です。
赤い部分をクリックすると「Name」の右に情報が出てくるので、「Preview」をクリックするとエラーが発生している場合はそこにスタックトレースが表示されました。
非同期でない場合、ページ上に表示されるはずのエラーがこの「Preview」に表示されるようです。
<img width="804" alt="スクリーンショット 2017-08-20 19.35.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/121811/edd7f695-39bb-77f1-1cee-a4140fa388e2.png">

以上、参考になれば幸いです。