Merge pull request #15 from pleshevskiy/bug-14
fix: filter undefined variable values
This commit is contained in:
commit
e303485f58
6 changed files with 5639 additions and 22 deletions
8
jest.config.js
Normal file
8
jest.config.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
testRegex: 'tests/.*\\.spec\\.ts',
|
||||||
|
testEnvironment: 'jsdom',
|
||||||
|
preset: 'ts-jest',
|
||||||
|
moduleFileExtensions: ['ts', 'js', 'json'],
|
||||||
|
collectCoverage: true,
|
||||||
|
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'],
|
||||||
|
};
|
5517
package-lock.json
generated
5517
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -9,7 +9,9 @@
|
||||||
"target"
|
"target"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "tsc"
|
"test": "jest",
|
||||||
|
"prepublishOnly": "tsc",
|
||||||
|
"report-coverage": "cat coverage/lcov.info | coveralls"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -34,6 +36,7 @@
|
||||||
"tiny-invariant": "^1.1.0"
|
"tiny-invariant": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/jest": "^26.0.15",
|
||||||
"@types/lodash.isequal": "^4.5.5",
|
"@types/lodash.isequal": "^4.5.5",
|
||||||
"@types/react": "^16.9.55",
|
"@types/react": "^16.9.55",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.6.1",
|
"@typescript-eslint/eslint-plugin": "^4.6.1",
|
||||||
|
@ -41,6 +44,8 @@
|
||||||
"eslint": "^7.12.1",
|
"eslint": "^7.12.1",
|
||||||
"eslint-plugin-react": "^7.21.5",
|
"eslint-plugin-react": "^7.21.5",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
|
"jest": "^26.6.3",
|
||||||
|
"ts-jest": "^26.4.3",
|
||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
src/misc.ts
20
src/misc.ts
|
@ -5,29 +5,37 @@ export function isObject(val: any) {
|
||||||
|
|
||||||
export function formDataFromObject(obj: Record<string, any>) {
|
export function formDataFromObject(obj: Record<string, any>) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
for (const [key, value] of Object.entries(obj)) {
|
Object.entries(obj)
|
||||||
|
.filter(([_, value]) => value !== undefined)
|
||||||
|
.forEach(([key, value]) => {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
value.forEach(val => formData.append(key, val));
|
value
|
||||||
|
.filter(val => val !== undefined)
|
||||||
|
.forEach(val => formData.append(key, val));
|
||||||
} else if (isObject(value)) {
|
} else if (isObject(value)) {
|
||||||
formData.set(key, JSON.stringify(value));
|
formData.set(key, JSON.stringify(value));
|
||||||
} else {
|
} else {
|
||||||
formData.set(key, value);
|
formData.set(key, value);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function urlSearchParamsFromObject(obj: Record<string, any>) {
|
export function urlSearchParamsFromObject(obj: Record<string, any>) {
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
for (const [key, value] of Object.entries(obj)) {
|
Object.entries(obj)
|
||||||
|
.filter(([_, value]) => value !== undefined)
|
||||||
|
.forEach(([key, value]) => {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
const arrayKey = `${key}[]`;
|
const arrayKey = `${key}[]`;
|
||||||
value.forEach(val => searchParams.append(arrayKey, val));
|
value
|
||||||
|
.filter(val => val !== undefined)
|
||||||
|
.forEach(val => searchParams.append(arrayKey, val));
|
||||||
} else {
|
} else {
|
||||||
searchParams.set(key, value);
|
searchParams.set(key, value);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return searchParams;
|
return searchParams;
|
||||||
}
|
}
|
||||||
|
|
81
tests/misc.spec.ts
Normal file
81
tests/misc.spec.ts
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import { formDataFromObject, isObject, urlSearchParamsFromObject } from '../src/misc';
|
||||||
|
|
||||||
|
describe('misc', () => {
|
||||||
|
describe('isObject', () => {
|
||||||
|
it('should return thruthy successfully', () => {
|
||||||
|
expect(isObject({})).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return falsy', () => {
|
||||||
|
expect(isObject(1)).toBeFalsy();
|
||||||
|
expect(isObject(true)).toBeFalsy();
|
||||||
|
expect(isObject('')).toBeFalsy();
|
||||||
|
expect(isObject([])).toBeFalsy();
|
||||||
|
expect(isObject(function () { return null; })).toBeFalsy();
|
||||||
|
expect(isObject(null)).toBeFalsy();
|
||||||
|
expect(isObject(undefined)).toBeFalsy();
|
||||||
|
expect(isObject(NaN)).toBeFalsy();
|
||||||
|
expect(isObject(Infinity)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('formDataFromObject', () => {
|
||||||
|
it('should convert object to form data successfully', () => {
|
||||||
|
const formData = formDataFromObject({
|
||||||
|
id: 1,
|
||||||
|
name: 'John',
|
||||||
|
status: ['ACTIVE', 'NOT_ACTIVE'],
|
||||||
|
user: {
|
||||||
|
name: 'John'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(formData).toBeInstanceOf(FormData);
|
||||||
|
expect(formData.get('id')).toBe('1');
|
||||||
|
expect(formData.get('name')).toBe('John');
|
||||||
|
expect(formData.getAll('status')).toEqual(['ACTIVE', 'NOT_ACTIVE']);
|
||||||
|
expect(formData.get('user')).toBe('{"name":"John"}');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter undefined values successfully', () => {
|
||||||
|
const formData = formDataFromObject({
|
||||||
|
id: undefined,
|
||||||
|
status: [undefined],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(formData.has('id')).toBeFalsy();
|
||||||
|
expect(formData.has('status')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('urlSearchParamsFromObject', () => {
|
||||||
|
it('should convert object to search params successfully', () => {
|
||||||
|
const searchParams = urlSearchParamsFromObject({
|
||||||
|
id: 1,
|
||||||
|
name: 'John',
|
||||||
|
status: ['ACTIVE', 'NOT_ACTIVE']
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(searchParams).toBeInstanceOf(URLSearchParams);
|
||||||
|
expect(searchParams.toString()).toBe('id=1&name=John&status%5B%5D=ACTIVE&status%5B%5D=NOT_ACTIVE');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encode value as uri component successfully', () => {
|
||||||
|
const searchParams = urlSearchParamsFromObject({
|
||||||
|
name: '@',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(searchParams.toString()).toBe('name=%40');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter undefined values successfully', () => {
|
||||||
|
const searchParams = urlSearchParamsFromObject({
|
||||||
|
id: 1,
|
||||||
|
name: undefined,
|
||||||
|
status: ['ACTIVE', undefined],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(searchParams.toString()).toBe('id=1&status%5B%5D=ACTIVE');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -14,9 +14,9 @@
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"declaration": true,
|
"declaration": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src",
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue