LoginSignup
55
46

More than 5 years have passed since last update.

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

Posted at

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

■前提

・Laravel5.4
・Vue.js2.x
・axios

■最終的なソースコード

API側

// 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コンポーネント側

<!--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を設定しないといけないのですが、それをつけ忘れてました。

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

②v-modelでデータを取得する際の記述間違い

例えばv-modelでtitlecontentを設定した場合、入力されたデータをmethodsで使うには、以下のようにthisをつける。

methods: {
   postArticle(){
     var article = {
       'title': this.title,
       'content': this.content
     };
  }

※テンプレート内で使う場合はthisをつける必要はない

<p>{{ title }}</p>

いづれにしてもdata()で変数を宣言しておく必要がある。

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

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

Userモデルにメソッドを定義してなくて、api.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」に表示されるようです。
スクリーンショット 2017-08-20 19.35.27.png

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

55
46
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
46