Vue.js

【Vue.js】Uncaught (in promise) TypeError: Cannot set property ‘login_user’ of undefinedというエラーを勉強してみる

まずはやろうとしていたこと

<script>

export default {

    data() {
        return {
            login_user: {}
        }
    },

    created() {
        this.getLoginUser()
    },

    methods: {
        async getLoginUser() {
            await axios.get("/api/users/logined") // ①
            .then(function(response) {
                this.login_user = response.data // ②
            })
        },
    }
}
</script>


axios.get(“/api/users/logined”)で自作のAPIを叩いてログインしているユーザーがいるか判断して取得する処理を呼び出しています。


エラーなく、うまく取得できたら、this.login_user = response.dataで、template内で使うために取得しています。

エラー文の解釈

Uncaught (in promise) TypeError: Cannot set property ‘login_user’ of undefined

Uncaught TypeError→直訳すると取得できなかったタイプのエラー
(caughtは、catchの過去形で、unは否定を表しています。)

Cannot set property ‘login_user’ of undefined→直訳すると、定義されていない”login_user”というものはセットできない。

つまり、変数login_userが定義されていない、って言われています。

変数の中身を確かめながらデバッグしていく

まずはコードに誤りがないか確認し、、、、→無かったです。

<script>

export default {

    methods: {
        async getLoginUser() {
            await axios.get("/api/users/logined")
            console.log(this.login_user) // ←① 空で表示されるはず
            .then(function(response) {
                this.login_user = response.data
                console.log(this.login_user) // ←② apiからの戻り値が格納されるはず
            })
        },
    }
}
</script>

①,②
変数が定義されていることが確認できたので、中身をみるために、上記のようにconsoleを用いて確認します。

すると、①では、undefinedと表示され、②の箇所の前でエラーが出ていることがわかります。

だいたいここで察しがついて、thisの扱いが間違ってるな、と僕はなりました。

解決

結論からいうと、thisのスコープとfunctionの関係を理解していなかったことが原因です。

参考:JavaScript の this を理解する多分一番分かりやすい説明

以下のように、.thenで呼出すfunctionの前にthisを別の変数vmに格納しておきます。

<script>

export default {

    methods: {
        async getLoginUser() {
            var vm = this  追加
            await axios.get("/api/users/logined")
            .then(function(response) {
               vm.login_user = response.data // 変更
            })
        },
    }
}
</script>

thisで書きたい場合はアロー関数を使う

<script>

export default {

    methods: {
        async getLoginUser() {
            await axios.get("/api/users/logined")
            .then(response => { // アロー関数
                this.login_user = response.data
            })
        },
    }
}
</script>

COMMENT

メールアドレスが公開されることはありません。