Maison > Questions et réponses > le corps du texte
J'ai un point de terminaison d'enregistrement simple que je souhaite permettre aux utilisateurs de s'inscrire dans mon application vue, je souhaite également afficher les erreurs appropriées au client vue depuis mon backend.
La structure JSON de l'erreur ressemble à ceci :
{ "errors": { "Password": [ "Password is required", "Minimum length of 8 characters is required" ], "UserName": [ "Username is required", "Minimum length of 6 characters is required" ], "EmailAddress": [ "Email Address is required", "Invalid Email Address" ], "ConfirmPassword": [ "Confirm Password is required" ] } }
J'ai un composable avec une fonction de registre comme celle-ci :
export default function useAuth() { let errors = ref({}) const register = (request) => { errors = {} AuthService.register(request) .then(res => { console.log("res: "+ res) }) .catch(err => { const errList = err.response.data.errors; errors = errList // Here i'm getting a reponse console.log(errors) }) } return { register, errors } }
J'ai également un composant de formulaire qui n'est qu'un simple formulaire avec des modèles en V ajoutés :
<script> // Imports.. export default { components: {}, setup() { const { register, errors} = useAuth(); const request = { userName: "", emailAddress: "", password: "", confirmPassword: "", }; const handleSubmit = () => { register(request); // empty object console.log(errors) }; return { errors, request, handleSubmit }; }, }; </script>
Dans mon composable, je peux déconnecter la réponse d'erreur comme ceci
Réponse d'erreur
J'ai essayé de désenregistrer l'erreur dans le composant formulaire mais maintenant j'obtiens juste un objet vide (j'utilise réactif pour gérer cet objet d'erreur dans le composable)
Réponse d'objet vide à partir d'éléments composables
P粉5761849332023-09-07 12:38:14
On dirait que vous renvoyez un tableau, pas un objet.
Donc, pour y accéder, vous devez faire errors[0].Password
.
Allez-vous utiliser un objet ou un tableau (cela peut être utile si vous avez plusieurs erreurs) ?
Si le tableau est attendu et que vous devez vérifier l'attribut Password
pour toutes les erreurs, vous feriez quelque chose comme ceci :
errors.find(err => !!err.Password).Password
P粉1808446192023-09-07 09:50:32
Il contient plusieurs erreurs, ce qui rend difficile pour moi de fournir une réponse concise qui corresponde à vos besoins. Au lieu de cela, j'ai rapidement créé un extrait de code qui fonctionne selon vos principes. À l’avenir, j’essaierai de mettre en évidence les points à surveiller et de fournir de bons conseils pour l’avenir.
async function()
可以等待Promise
console.log
证明使用async
si vous souhaitez utiliser les résultats immédiatement) // YOUR CODE const handleSubmit = () => { register(request); // call PROMISE () // empty object console.log(errors) };
Cela ne fournit pas de résultats immédiats ; l'exécution sur un thread séparé prend un certain temps. En conséquence, le script JavaScript avance presque immédiatement. Normalement, cela entraînera une erreur si vous souhaitez utiliser le résultat immédiatement car la réponse n'est pas encore arrivée.
Donc, lorsque vous essayez d'accéder à errors
的新结果时,您会看到它是空的,即使在 console.log
之后,1-2 秒后,它不会再为空,因为 register()
, cela a déjà été exécuté.
// SUCCESSFULLY USING const handleSubmit = async () => { await register(request); // call PROMISE () AND WAIT response by await // empty object console.log(errors) };
等待
- Attendez la fin du processus - Documentation MDN
异步函数
- 需要什么await
Utilisation de - Documentation MDN
ref()
avec VueJS ? Stockez les valeurs enregistrées par ref()
、reactive()
、compulated()
, reactive()
, compulated()
, etc. dans des variables non modifiables. Utilisez toujours const lors de la déclaration de ces variables.
Plus d'informations - Réponses StackOverflow
// YOUR CODE let errors = ref({})
const errors = ref({})
Vous utilisez le suffixe .value
dans une instance et pas dans une autre. Eh bien, ce qui se passe, c'est que le résultat d'une variable .value
后缀,而在另一实例中则不使用。嗯,情况是 ref()
变量的结果始终存储在 .value
est toujours stocké dans .value
. Vous pouvez le manipuler en conséquence.
// YOUR CODE let errors = ref({}) // and... errors = {...}
const errors = ref({}) // and... errors.value = {...}
Comment utiliser ref()
? - Documentation VueJS
J'ai commenté ces lignes pour mieux comprendre le code. J'espère que cela est compréhensible.
/** ** Need more function for example ** !!! The vue is below !!! */ // CDN Vue Import const { createApp, ref, computed } = Vue // isValideEmail() (JUST EXAMPLE FOR SNIPPET) // Helper function to validate email address function isValidEmail(email) { const emailRegex = /^\S+@\S+\.\S+$/; return emailRegex.test(email); } // AuthService (JUST EXAMPLE FOR SNIPPET) class AuthServiceClass { errors constructor() { this.errors = {}; } register(inputs) { // Reset Errors this.errors = {}; console.log(inputs) // Check the UserName field if (!inputs.userName) { this.errors.UserName = (this.errors?.UserName ?? []).concat("Username is required"); } if (!inputs.userName || inputs.userName.length < 6) { this.errors.UserName = (this.errors?.UserName ?? []).concat("Minimum length of 6 characters is required"); } // Check the EmailAddress field if (!inputs.emailAddress) { this.errors.EmailAddress = (this.errors?.EmailAddress ?? []).concat("Email Address is required"); } if (!inputs.emailAddress || !isValidEmail(inputs.emailAddress)) { this.errors.EmailAddress = (this.errors?.EmailAddress ?? []).concat("Invalid Email Address"); } // Check the Password field if (!inputs.password) { this.errors.Password = (this.errors?.Password ?? []).concat("Password is required"); } if (!inputs.password || inputs.password.length < 8) { this.errors.Password = (this.errors?.Password ?? []).concat("Minimum length of 8 characters is required"); } // Check the ConfirmPassword field if (!inputs.confirmPassword) { this.errors.ConfirmPassword = (this.errors?.ConfirmPassword ?? []).concat("Confirm Password is required"); } // Return with Promise because its just a simulate your really AuthService.register return new Promise((resolve, reject) => { if (this.errors.length !== 0) { reject({ errors: this.errors }); } else { resolve({ success: true, errors: null }); } }); } } // Import AuthService (JUST EXAMPLE FOR SNIPPET) const AuthService = new AuthServiceClass() // Declare useAuth() (JUST EXAMPLE FOR SNIPPET) function useAuth() { const errors = ref({}) const register = async (request) => { await AuthService.register(request) .then(res => { console.log("AuthService Register Successfully Response", res) }) .catch(err => { console.log("AuthService Register Error Response", err) const newErrors = err.errors; errors.value = newErrors }) } return { register, errors } } /** ** !!!!!! ** Here's started vue code snippet */ // Component.vue const app = createApp({ setup() { // Get register() and errors Ref const { register, errors } = useAuth(); // Declare Ref Object for inputs const request = ref({ userName: "", emailAddress: "", password: "", confirmPassword: "", }); // Declare Submit Function (async for Promise check !!!) const handleSubmit = async () => { console.log('') // just log console.log('Detect New Handle') // just log // call register() function with our value of inputs // wait answer by "await" await register(request.value); console.log('HandleSubmit - Check Error List', errors.value) // just log }; // Just Extra Computed Value, not important // return true/false const hasError = computed(() => Object.keys(errors.value).length > 0) return { hasError, errors, request, handleSubmit } }, }).mount('#app')
.input { display: flex; flex-direction: column; gap: 2px; margin-bottom: 10px; max-width: 200px; } .error { color: red; }
<!-- Component.vue --> <script src="https://unpkg.com/vue@3.3.4/dist/vue.global.prod.js"></script> <div id="app"> <div> <!-- Display Errors --> <div v-if="hasError"> <!-- errors is an object, so you can foreach its keys --> <div v-for="inputName of Object.keys(errors)"> <span>{{ inputName }}:</span> <!-- name-array pairs can be directly printed as error messages --> <div v-for="errorMessage of errors[inputName]" class="error"> {{ errorMessage }} </div> </div> </div> <!-- Inputs --> <!-- request is an object, so you can foreach its keys --> <div class="input" v-for="inputName of Object.keys(request)"> <label>{{ inputName }}</label> <input v-model="request[inputName]" /> </div> <!-- Submit Button --> <button @click="handleSubmit">Submit</button> </div> </div>