fix: Add error handling to Settings form
This commit adds error handling to the settings form in the Settings.vue page. A new 'errors' object has been introduced to capture and display errors returned from the API. The onSubmit event also has been modified for handling a try/catch block for potential API errors. The associated unit test was updated to ensure proper behavior when an API error is returned. This improvement aims to provide a better user experience by clearly communicating issues with the user's changes. close #58
This commit is contained in:
parent
1ba77588f1
commit
ece4466b7a
|
|
@ -1,3 +1,4 @@
|
|||
import userEvent from '@testing-library/user-event'
|
||||
import { fireEvent, render, waitFor } from '@testing-library/vue'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { router } from 'src/router.ts'
|
||||
|
|
@ -80,4 +81,16 @@ describe('# Settings Page', () => {
|
|||
}
|
||||
`)
|
||||
})
|
||||
|
||||
it('should display error message when api returned some errors', async () => {
|
||||
server.use(['PUT', '/api/user', 400, { errors: { username: ['has already been taken'] } }])
|
||||
const { getByRole, getByPlaceholderText, getByText } = render(Settings, renderOptions({
|
||||
initialState: { user: { user: fixtures.user } },
|
||||
}))
|
||||
|
||||
await userEvent.type(getByPlaceholderText('Your name'), 'new username')
|
||||
await userEvent.click(getByRole('button', { name: 'Update Settings' }))
|
||||
|
||||
expect(getByText('username has already been taken')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@
|
|||
Your Settings
|
||||
</h1>
|
||||
|
||||
<ul class="error-messages">
|
||||
<li v-for="(error, field) in errors" :key="field">
|
||||
{{ field }} {{ error ? error[0] : '' }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form @submit.prevent="onSubmit">
|
||||
<fieldset>
|
||||
<fieldset class="form-group">
|
||||
|
|
@ -75,22 +81,31 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive } from 'vue'
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { routerPush } from 'src/router'
|
||||
import { api } from 'src/services'
|
||||
import { api, isFetchError } from 'src/services'
|
||||
import type { UpdateUser } from 'src/services/api'
|
||||
import { useUserStore } from 'src/store/user'
|
||||
|
||||
const form: UpdateUser = reactive({})
|
||||
|
||||
const userStore = useUserStore()
|
||||
const errors = ref()
|
||||
|
||||
const onSubmit = async () => {
|
||||
errors.value = {}
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line unicorn/no-array-reduce
|
||||
const filteredForm = Object.entries(form).reduce((form, [k, v]) => v === null ? form : Object.assign(form, { [k]: v }), {})
|
||||
const userData = await api.user.updateCurrentUser({ user: filteredForm }).then(res => res.data.user)
|
||||
userStore.updateUser(userData)
|
||||
await routerPush('profile', { username: userData.username })
|
||||
} catch (error) {
|
||||
if (isFetchError(error)) {
|
||||
errors.value = error.error?.errors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onLogout = async () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue