Skip to content

Commit 47c71ca

Browse files
authored
Merge pull request #782 from chantouchsek/feat/781-optimiz-util
Feat/781 optimize util
2 parents 0bb4ef1 + 4b19735 commit 47c71ca

File tree

6 files changed

+37
-59
lines changed

6 files changed

+37
-59
lines changed

src/__tests__/object.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { hasFiles, hasOwnProperty, isFile } from '../util'
1+
import { hasFiles, isFile } from '../util'
22

33
describe('Object Test', () => {
44
// const { window, File } = global
@@ -10,9 +10,6 @@ describe('Object Test', () => {
1010
const file = new File(['hello world!'], 'myfile')
1111
expect(isFile(file)).toBeTruthy()
1212
})
13-
it('should check has own property', function () {
14-
expect(hasOwnProperty({ dev: null }, '')).toBeFalsy()
15-
})
1613
it('check if window is undefined', () => {
1714
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1815
// @ts-ignore

src/core/BaseService.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { AxiosError, AxiosInstance, Method, AxiosRequestConfig, AxiosResponse } from 'axios'
22
import type { IParseOptions } from 'qs'
3-
import { isObject, isArray } from 'lodash'
3+
import { isObject } from 'lodash'
44
import qs from 'qs'
55
import Validator from './Validator'
66
import { hasFiles, objectToFormData } from '../util'
@@ -86,11 +86,12 @@ export default class BaseService {
8686
$submit<T = any, F = any>(method: Method, param?: string | number, form?: F, config?: AxiosRequestConfig) {
8787
this.beforeSubmit()
8888
return new Promise<AxiosResponse<T>>((resolve, reject) => {
89-
const data = hasFiles(form) ? objectToFormData(form) : form
90-
const endpoint = param ? `/${this.endpoint}/${param}` : `/${this.endpoint}`
91-
const url = this.__getParameterString(endpoint.replace(/\/\//g, '/'))
92-
config = Object.assign({}, config, { url, data, method })
93-
this.$http(config)
89+
const formData = hasFiles(form) ? objectToFormData(form) : form
90+
const endpointPath = param ? `/${this.endpoint}/${param}` : `/${this.endpoint}`
91+
const endpoint = endpointPath.replace(/\/\//g, '/')
92+
const url = this.__getParameterString(endpoint)
93+
const axiosConfig = { url, data: formData, method, ...config }
94+
this.$http(axiosConfig)
9495
.then((response) => {
9596
this.onSuccess()
9697
resolve(response)
@@ -101,9 +102,9 @@ export default class BaseService {
101102
const { response } = error
102103
if (response && response.status === UNPROCESSABLE_ENTITY) {
103104
const { data } = response
104-
const errors: Record<string, any> = {}
105-
Object.assign(errors, data[this.$errorProperty])
106-
this.onFail(errors)
105+
const validationErrors: Record<string, any> = {}
106+
Object.assign(validationErrors, data[this.$errorProperty])
107+
this.onFail(validationErrors)
107108
}
108109
reject(error)
109110
})
@@ -148,7 +149,7 @@ export default class BaseService {
148149
removeParameters(parameters: string[] = []) {
149150
if (!parameters || !parameters.length) {
150151
this.parameters = {}
151-
} else if (isArray(parameters)) {
152+
} else if (Array.isArray(parameters)) {
152153
for (const parameter of parameters) delete this.parameters[parameter]
153154
}
154155
return this

src/core/Validator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class Validator {
117117
}
118118

119119
fields(field: string | string[]): string[] {
120-
const fields = []
120+
const fields: string[] = []
121121
if (Array.isArray(field)) {
122122
for (const f of field) {
123123
fields.push(toCamelCase(f), toSnakeCase(f))

src/util/formData.ts

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { hasOwnProperty, isArray, isFile } from './objects'
1+
import { isFile } from './objects'
22

3-
const getKey = (parent: any, property: any) => (parent ? parent + '[' + property + ']' : property)
43
export function objectToFormData(obj: any, formData = new FormData(), parent = ''): FormData {
5-
if (obj === null || obj === 'undefined' || obj.length === 0) {
4+
if (obj == null || (Array.isArray(obj) && obj.length === 0)) {
65
formData.append(parent, obj)
76
} else {
8-
for (const property in obj) {
9-
if (hasOwnProperty(obj, property)) {
10-
appendToFormData(formData, getKey(parent, property), obj[property])
11-
}
7+
const propertyMap = new Map(Object.entries(obj))
8+
for (const [property, value] of propertyMap) {
9+
const key = parent ? `${parent}[${property}]` : property
10+
appendToFormData(formData, key, value)
1211
}
1312
}
1413
return formData
@@ -19,7 +18,7 @@ function appendToFormData(formData: FormData, key: string, value: any) {
1918
if (typeof value === 'boolean') return formData.append(key, value ? '1' : '0')
2019
if (value === null) return formData.append(key, '')
2120
if (typeof value !== 'object') return formData.append(key, value)
22-
if (isArray(value) && hasFilesDeep(value)) {
21+
if (Array.isArray(value) && hasFilesDeep(value)) {
2322
for (let i = 0; i < value.length; i++) {
2423
formData.append(key + '[' + i + ']', value[i], value[i].name)
2524
}
@@ -28,28 +27,27 @@ function appendToFormData(formData: FormData, key: string, value: any) {
2827
objectToFormData(value, formData, key)
2928
}
3029
export function hasFilesDeep(obj: any): boolean {
31-
if (obj === null) return false
30+
if (!obj) return false
31+
3232
if (typeof obj === 'object') {
33-
for (const key in obj) {
34-
if (isFile(obj[key])) return true
35-
}
33+
const objValues = Object.values(obj)
34+
if (objValues.some(isFile)) return true
3635
}
37-
if (isArray(obj)) {
38-
let f = ''
39-
for (const key in obj) {
40-
if (hasOwnProperty(obj, key)) {
41-
f = key
42-
break
43-
}
36+
37+
if (Array.isArray(obj)) {
38+
const nonNullElement = obj.find((el) => el !== null)
39+
if (nonNullElement) {
40+
return hasFilesDeep(nonNullElement)
4441
}
45-
return hasFilesDeep(obj[f])
4642
}
43+
4744
return isFile(obj)
4845
}
4946
export function hasFiles(form: any) {
5047
for (const prop in form) {
51-
const hasProp = hasOwnProperty(form, prop) || typeof window !== 'undefined'
52-
if (hasProp && hasFilesDeep(form[prop])) return true
48+
if (Object.prototype.hasOwnProperty.call(form, prop) && hasFilesDeep(form[prop])) {
49+
return true
50+
}
5351
}
5452
return false
5553
}

src/util/objects.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
1-
export function isArray(object: any): boolean {
2-
return Object.prototype.toString.call(object) === '[object Array]'
3-
}
4-
5-
export function hasOwnProperty(obj: any, key: any) {
6-
if (!obj || !key) return false
7-
return Object.prototype.hasOwnProperty.call(obj, key)
8-
}
9-
101
export function isFile(object: any): boolean {
11-
if (typeof window === 'undefined' || typeof File !== 'function' || typeof FileList !== 'function') {
12-
return false
13-
}
142
return object instanceof File || object instanceof FileList
153
}
16-
17-
export function is(errors: any, error: any): boolean {
18-
return isArray(error) ? error.some((w: string) => is(errors, w)) : errors.includes(error)
4+
export function is(errors: string[], errorsToCheck: string[] | string): boolean {
5+
return Array.isArray(errorsToCheck) ? errorsToCheck.some((w) => is(errors, w)) : errors.includes(errorsToCheck)
196
}

src/util/string.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
export const toCamelCase = (e: string) => {
2-
return e.replace(/_([a-z])/g, (g) => g[1].toUpperCase())
3-
}
4-
export const toSnakeCase = (e: string) => {
5-
if (!e.match(/([A-Z])/g)) return e
6-
return e.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
7-
}
1+
export const toCamelCase = (e: string) => e.replace(/_([a-z])/g, (g) => g[1].toUpperCase())
2+
export const toSnakeCase = (e: string) => (e.match(/([A-Z])/g) ? e.replace(/[A-Z]/g, (l) => `_${l.toLowerCase()}`) : e)

0 commit comments

Comments
 (0)