ElementUIでサーバサイドで発生したエラーのメッセージ表示
現在、ElementUIとNuxt.jsでサーバサイドで発生したエラー(一意制約違反)のメッセージを
Form-Item Attributesのerrorに設定することで表示させています。
一度目のエラーにおいては想定した通りに表示されるのですが、同じ値で再度ボタンをクリックした際は(待ちを入れないと)エラーメッセージが表示されません。
直接の原因は、データの変更が非同期に走っているから整合性がとれなくなっていることと推察しているのですが、そもそもこのような事象が発生しているのは使い方に誤りがあるのでしょうか?
2回目のエラー
想定しているエラーメッセージ:'{入力値}は既に使用されています。別のニックネームにしてください。'
実際のエラーメッセージ:''
該当のソースコード
長いですがまずはそのまま貼ります。
Vue(Nuxt)
1<template> 2 <section class="container"> 3 <el-form 4 ref="userForm" 5 :model="userForm" 6 :rules="rules" 7 @submit.native.prevent> 8 <el-form-item 9 ref="nickname" 10 :error="errorMessage" 11 label="ニックネームを登録してください。" 12 prop="nickname"> 13 <el-input 14 v-model="userForm.nickname" 15 type="text" 16 autocomplete="off"/> 17 </el-form-item> 18 <el-button 19 type="primary" 20 @click="registNickName">登録</el-button> 21 </el-form> 22 23 </section> 24</template> 25 26<script> 27import firebase from '@/plugins/firebase' 28import axios from 'axios' 29 30export default { 31 data: function() { 32 return { 33 userForm: { 34 nickname: '' 35 }, 36 errorMessage: '', 37 rules: { 38 nickname: [ 39 { 40 required: true, 41 whitespace: true, 42 message: 'ニックネームは必ず入力してください。' 43 } 44 ] 45 } 46 } 47 }, 48 methods: { 49 registNickName: async function() { 50 var isValid = false 51 this.$refs['userForm'].validate(valid => { 52 isValid = valid 53 }) 54 if (!isValid) { 55 return 56 } 57 const _outer = this 58 const idToken = await firebase.auth().currentUser.getIdToken() 59 const res = await axios({ 60 method: 'PUT', 61 url: 'http://localhost:8080/user/', 62 headers: { 63 Authorization: `Bearer ${idToken}` 64 }, 65 data: { 66 nickname: _outer.userForm.nickname 67 } 68 }).catch(function(error) { 69 var retVal = 500 70 if (error.response && error.response.status == 409) { 71 retVal = 409 72 } 73 return { 74 status: retVal 75 } 76 }) 77 78 if (res.status == 200) { 79 // 正常系 80 this.$router.push({ path: '/' }) 81 return 82 } 83 if (res.status == 409) { 84 // 一意制約(ニックネーム重複) 85 86 /* 87 XXX 2度目の時にthis.errorを一度クリアしないと発火しない。 88 ただし、少しまってやらないといけない。 89 データの変更が非同期に走っているから整合性がとれなくなっている? 90 */ 91 this.errorMessage = '' 92 await new Promise(function(resolve, reject) { 93 window.setTimeout(resolve, 10) 94 }) 95 const duplicateMessage = 96 this.userForm.nickname + 97 'は既に使用されています。別のニックネームにしてください。' 98 this.errorMessage = duplicateMessage 99 this.$message({ 100 message: duplicateMessage, 101 type: 'error' 102 }) 103 return 104 } else { 105 // その他エラー 106 this.$router.push({ path: '/error' }) 107 return 108 } 109 } 110 } 111} 112</script> 113 114<style> 115.container { 116 min-height: 100vh; 117 display: flex; 118 justify-content: center; 119 align-items: center; 120 text-align: center; 121} 122 123.links { 124 padding-top: 15px; 125} 126</style> 127
試したこと
registNickName関数の先頭で前回のエラーメッセージをクリア(this.errorMessage = '')
した場合はエラーメッセージが表示される。
現在の位置で待ちを入れた場合(await new Promise〜)はエラーメッセージが表示される。
現在の位置で待ちを入れない場合はエラーメッセージが表示されない。
補足情報(FW/ツールのバージョンなど)
node v10.15.0
element-ui "version": "2.4.11"
nuxt "version": "2.3.4",
あなたの回答
tips
プレビュー