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 { fireEvent, render, waitFor } from '@testing-library/vue'
|
||||||
import { describe, expect, it, vi } from 'vitest'
|
import { describe, expect, it, vi } from 'vitest'
|
||||||
import { router } from 'src/router.ts'
|
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
|
Your Settings
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
<ul class="error-messages">
|
||||||
|
<li v-for="(error, field) in errors" :key="field">
|
||||||
|
{{ field }} {{ error ? error[0] : '' }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<form @submit.prevent="onSubmit">
|
<form @submit.prevent="onSubmit">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
|
|
@ -75,22 +81,31 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, reactive } from 'vue'
|
import { computed, onMounted, reactive, ref } from 'vue'
|
||||||
import { routerPush } from 'src/router'
|
import { routerPush } from 'src/router'
|
||||||
import { api } from 'src/services'
|
import { api, isFetchError } from 'src/services'
|
||||||
import type { UpdateUser } from 'src/services/api'
|
import type { UpdateUser } from 'src/services/api'
|
||||||
import { useUserStore } from 'src/store/user'
|
import { useUserStore } from 'src/store/user'
|
||||||
|
|
||||||
const form: UpdateUser = reactive({})
|
const form: UpdateUser = reactive({})
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
const errors = ref()
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
// eslint-disable-next-line unicorn/no-array-reduce
|
errors.value = {}
|
||||||
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)
|
try {
|
||||||
userStore.updateUser(userData)
|
// eslint-disable-next-line unicorn/no-array-reduce
|
||||||
await routerPush('profile', { username: userData.username })
|
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 () => {
|
const onLogout = async () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue