-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.ts
114 lines (99 loc) · 3.26 KB
/
api.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import get from './getter';
import localStorage from './localStorage';
import { ApiResponse, UrlConfigType } from './types/api';
export function callApi(
urlConfig: UrlConfigType,
config: AxiosRequestConfig = {}
): Promise<ApiResponse<any>> {
return axios({
...urlConfig,
...config,
}).then(
(result: AxiosResponse<any>) => {
if (result.status !== 200 && get(result, 'data.status') !== 'ok') {
return Promise.reject(result);
}
if (get(result, 'data.status') === 'error') {
return Promise.reject(result);
}
const response = get(result, 'data.data') || get(result, 'data');
if (get(response, 'token')) {
localStorage.setItem('token', get(response, 'token'));
}
return response;
},
(error) => {
return Promise.reject(error);
}
);
}
/**
* Метод для отправки запроса к api.
* @param {UrlConfigType} urlConfig URL, на который нужно отправить запрос, вместе с методом запроса
* @param {any} data Тело запроса либо GET-параметры в виде объекта
* @param {AxiosRequestConfig} config Конфиг axios
* @param {boolean} multipartFormData Содержит ли запрос данные формы
* @param {boolean} withToken Для запросов с токеном из local storage
* @returns {ApiResponse} Если статус ответа 200, возвращает поле response с ответом от сервера,
* иначе поля error and errorData с информацией об ошибке.
*/
export default function api<R = any, E = any>(
urlConfig: UrlConfigType,
data: null | undefined | any = {},
config: AxiosRequestConfig = {},
multipartFormData = false,
withToken = true
): Promise<ApiResponse<R, E>> {
const queryConfig = { ...config };
if (
(queryConfig.data === null || queryConfig.data === undefined) &&
urlConfig.method !== 'GET'
) {
queryConfig.data = data;
}
if (!queryConfig.headers) {
queryConfig.headers = {};
}
if (multipartFormData) {
const formData = new FormData();
Object.keys(data).forEach((key) => {
const value = data[key];
if (Array.isArray(value)) {
value.forEach((item) => {
formData.append(key, item);
});
} else {
formData.append(key, value);
}
});
queryConfig.data = formData;
Object.assign(queryConfig.headers, {
'Content-Type': 'multipart/form-data',
});
}
if (localStorage.getItem('token') && withToken) {
Object.assign(queryConfig.headers, {
Authorization: `Bearer ${localStorage.getItem('token')}`,
});
}
if (urlConfig.method === 'GET') {
queryConfig.params = {
...data,
uid: localStorage.getItem('userId'),
};
} else {
queryConfig.params = {
uid: localStorage.getItem('userId'),
};
}
return callApi(urlConfig, queryConfig)
.then((response) => ({ response: response as R }))
.catch((error) => {
const responseError = get(error, 'response.data');
return {
error,
errorData: responseError ? (responseError as E) : undefined,
};
});
}