Vue Best practice по убиранию дублирования кода в методах отправки запросов

Рейтинг: 0Ответов: 1Опубликовано: 11.03.2023

У меня есть приложение на 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);