質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

ElementUIでサーバサイドで発生したエラーのメッセージ表示

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 542

kyoshitake

score 6

ElementUIでサーバサイドで発生したエラーのメッセージ表示

現在、ElementUIとNuxt.jsでサーバサイドで発生したエラー(一意制約違反)のメッセージを
Form-Item Attributesのerrorに設定することで表示させています。

一度目のエラーにおいては想定した通りに表示されるのですが、同じ値で再度ボタンをクリックした際は(待ちを入れないと)エラーメッセージが表示されません。

直接の原因は、データの変更が非同期に走っているから整合性がとれなくなっていることと推察しているのですが、そもそもこのような事象が発生しているのは使い方に誤りがあるのでしょうか?

2回目のエラー

想定しているエラーメッセージ:'{入力値}は既に使用されています。別のニックネームにしてください。'
実際のエラーメッセージ:'' 

該当のソースコード

長いですがまずはそのまま貼ります。

<template>
  <section class="container">
    <el-form
      ref="userForm"
      :model="userForm"
      :rules="rules"
      @submit.native.prevent>
      <el-form-item
        ref="nickname"
        :error="errorMessage"
        label="ニックネームを登録してください。"
        prop="nickname">
        <el-input
          v-model="userForm.nickname"
          type="text"
          autocomplete="off"/>
      </el-form-item>
      <el-button
        type="primary"
        @click="registNickName">登録</el-button>
    </el-form>

  </section>
</template>

<script>
import firebase from '@/plugins/firebase'
import axios from 'axios'

export default {
  data: function() {
    return {
      userForm: {
        nickname: ''
      },
      errorMessage: '',
      rules: {
        nickname: [
          {
            required: true,
            whitespace: true,
            message: 'ニックネームは必ず入力してください。'
          }
        ]
      }
    }
  },
  methods: {
    registNickName: async function() {
      var isValid = false
      this.$refs['userForm'].validate(valid => {
        isValid = valid
      })
      if (!isValid) {
        return
      }
      const _outer = this
      const idToken = await firebase.auth().currentUser.getIdToken()
      const res = await axios({
        method: 'PUT',
        url: 'http://localhost:8080/user/',
        headers: {
          Authorization: `Bearer ${idToken}`
        },
        data: {
          nickname: _outer.userForm.nickname
        }
      }).catch(function(error) {
        var retVal = 500
        if (error.response && error.response.status == 409) {
          retVal = 409
        }
        return {
          status: retVal
        }
      })

      if (res.status == 200) {
        // 正常系
        this.$router.push({ path: '/' })
        return
      }
      if (res.status == 409) {
        // 一意制約(ニックネーム重複)

        /*
          XXX 2度目の時にthis.errorを一度クリアしないと発火しない。
          ただし、少しまってやらないといけない。
          データの変更が非同期に走っているから整合性がとれなくなっている?
         */
        this.errorMessage = ''
        await new Promise(function(resolve, reject) {
          window.setTimeout(resolve, 10)
        })
        const duplicateMessage =
          this.userForm.nickname +
          'は既に使用されています。別のニックネームにしてください。'
        this.errorMessage = duplicateMessage
        this.$message({
          message: duplicateMessage,
          type: 'error'
        })
        return
      } else {
        // その他エラー
        this.$router.push({ path: '/error' })
        return
      }
    }
  }
}
</script>

<style>
.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

.links {
  padding-top: 15px;
}
</style>

試したこと

registNickName関数の先頭で前回のエラーメッセージをクリア(this.errorMessage = '')
した場合はエラーメッセージが表示される。
現在の位置で待ちを入れた場合(await new Promise〜)はエラーメッセージが表示される。
現在の位置で待ちを入れない場合はエラーメッセージが表示されない。

補足情報(FW/ツールのバージョンなど)

node v10.15.0    
element-ui "version": "2.4.11"
nuxt "version": "2.3.4",

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる