Vue Best practice по убиранию дублирования кода в методах отправки запросов
У меня есть приложение на Vue (composition API) с использованием библиотеки компонентов Quasar. Бывает, такое, что какой-то компонент может отправлять до 3-5 запросов на сервер для выполнения каких-либо CRUD операций и они выглядят однообразно, может быть, разве что, с незначительными отличиями, например, отображать прелоадер или нет, добавить данные в хранилище или нет и т.д., но основные действия одинаковы: запрос, успешное действие, отлов ошибки, уведомление. Пример скапливания однообразных методов из приложения "Списки задач":
const getTaskLists = async () => {
await API.get('tasks').then(response => {
taskLists.value = response.data.lists
loading.value = false
}).catch(error => {
$q.notify({
type: 'negative',
message: `Server Error: ${error}`
})
loading.value = false
})
}
const createTaskList = async () => {
const listName = model.value.newListName
model.value.newListName = ''
await API.put('tasks/list/store', {
'title': listName
}).then(response => {
$q.notify({
type: 'positive',
message: 'Список успешно добавлен!'
})
taskLists.value.push(response.data.lists)
}).catch(error => {
$q.notify({
type: 'negative',
message: `Server Error: ${error.response.data.message}`
})
})
}
const deleteTaskList = async listId => {
await API.get(`tasks/list/${listId}/delete`).then(response => {
$q.notify({
type: 'positive',
message: 'Список успешно удалён!'
})
}).catch(error => {
$q.notify({
type: 'negative',
message: `Server Error: ${error}`
})
})
}
Какие есть best practice для универсализации подобных участков кода?
п.с. в коде API - это слой над axios с надстройками - для авторизации и т.д.
Ответы (1 шт):
Можно использовать декораторы:
function loadingDecorator<T>(fn: () => Promise<T>, loadingRef: Ref<boolean>) {
return function () {
loadingRef.value = true;
return fn()
.then(() =>
void $q.notify({
type: 'positive',
message: 'Список успешно добавлен!'
})
)
.catch((error) =>
void $q.notify({
type: 'negative',
message: `Server Error: ${error.response.data.message}`
})
)
.finally(() => (loadingRef.value = false));
};
}
И
const loadTaskLists = loadingDecorator(getTaskLists, loading);