Skip to content

Commit 26a859e

Browse files
Chantouch SekChantouch Sek
authored andcommitted
feat(update): :rocket added ability to accept parameter only a key string
1 parent 2d887d8 commit 26a859e

File tree

9 files changed

+163
-26
lines changed

9 files changed

+163
-26
lines changed

README.md

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Vue Api Queries.
22

3+
[![Build Status](https://travis-ci.com/Chantouch/vue-api-queries.svg?branch=master)](https://travis-ci.com/Chantouch/vue-api-queries)
34
[![Latest Version on NPM](https://img.shields.io/npm/v/vue-api-queries.svg?style=flat-square)](https://npmjs.com/package/vue-api-queries)
45
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
56
[![npm](https://img.shields.io/npm/dt/vue-api-queries.svg?style=flat-square)](https://npmjs.com/package/vue-api-queries)
@@ -305,9 +306,76 @@ Method | Description
305306
**has(attributes)** | To check multiple attributes given have any errors
306307
**first(attribute)** | To get errors message by an attribute
307308

308-
## Todo
309-
### Add tests
309+
310+
## How to use in vue component
311+
312+
```vue
313+
<template>
314+
<v-form v-model="valid" lazy-validation @keydown.native="$errors.onKeydown" @submit.prevent='submit'>
315+
<v-container>
316+
<v-row>
317+
<v-col cols="12" md="4">
318+
<v-text-field
319+
v-model="firstname"
320+
:error-messages="$errors.first(['firstname'])"
321+
:counter="10"
322+
label="First name"
323+
required
324+
name="firstname"
325+
@focus="validate"
326+
/>
327+
</v-col>
328+
<v-col cols="12" md="4">
329+
<v-text-field
330+
v-model="lastname"
331+
:counter="10"
332+
label="Last name"
333+
required
334+
:error-messages="$errors.first(['lastname'])"
335+
/>
336+
</v-col>
337+
<v-col cols="12" md="4">
338+
<v-text-field
339+
v-model="email"
340+
:counter="10"
341+
label="Email"
342+
required
343+
:error-messages="$errors.first('email')"
344+
/>
345+
</v-col>
346+
<v-col cols="12" md="4">
347+
<v-text-field v-model="email" label="E-mail" required />
348+
</v-col>
349+
</v-row>
350+
</v-container>
351+
</v-form>
352+
</template>
353+
<script>
354+
export default {
355+
data: () => ({
356+
valid: false,
357+
firstname: '',
358+
lastname: '',
359+
email: '',
360+
}),
361+
methods: {
362+
submit() {
363+
this.$axios.$post('/account/create', {
364+
firstname: this.firstname,
365+
lastname: this.lastname,
366+
email: this.email
367+
})
368+
}
369+
},
370+
beforeDestroy() {
371+
this.$errors.flush()
372+
}
373+
}
374+
</script>
375+
```
310376

311377
# Contact
312378

379+
380+
313381
Twitter [@DevidCs83](https://twitter.com/DevidCs83)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
"nuxt"
8383
],
8484
"dependencies": {
85-
"axios": "^0.20.0",
85+
"axios": "^0.21.1",
8686
"camelcase-keys": "^6.2.2",
8787
"escape-string-regexp": "^4.0.0",
8888
"lodash.merge": "^4.6.2",

src/__tests__/base-proxy.test.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { ValidatorType } from '../core/Validator'
66
import Validator from '../core/Validator'
77
import BaseTransformer from '../core/BaseTransformer'
88
import PaginationTransformer from '../core/PaginationTransformer'
9+
import { merge } from '../util/objects'
910

1011
let proxy: PostProxy
1112
let mockAdapter
@@ -14,12 +15,21 @@ let validator: ValidatorType
1415
describe('BaseProxy', () => {
1516
beforeEach(() => {
1617
validator = Validator
17-
const axios = Axios.create({ baseURL: 'http://drink-order-api.test' })
18+
const axios = Axios.create({ baseURL: 'http://mock-api.test' })
1819
BaseProxy.$http = axios
1920
proxy = new PostProxy()
2021
mockAdapter = new MockAdapter(axios)
2122
})
2223

24+
it('check if http was installed', async () => {
25+
BaseProxy.$http = null
26+
try {
27+
await proxy.all()
28+
} catch (e) {
29+
expect(e.message).toBe('Vue Api Queries, No http library provided.')
30+
}
31+
})
32+
2333
it('it should fetch items with pagination', async () => {
2434
const items = {
2535
data: [{ first_name: 'Chantouch', last_name: 'Sek' }],
@@ -74,6 +84,28 @@ describe('BaseProxy', () => {
7484
.all()
7585
expect(data).toEqual(items)
7686
})
87+
88+
it('should set parameter with empty value', async () => {
89+
const user1 = {
90+
first_name: 'Dara',
91+
last_name: 'Hok',
92+
id: 1,
93+
songs: [1, 2, 3],
94+
}
95+
const user2 = merge(user1, {
96+
last_name: 'Hok 01',
97+
songs: [4, 5, 6],
98+
song: { name: 'Love song...' },
99+
pc: null,
100+
})
101+
const items = [user2, { first_name: 'Chantouch', last_name: 'Sek', id: 2 }]
102+
mockAdapter.onGet('/posts?id=1&first_name=Dara').reply(200, { data: items })
103+
const { data } = await proxy
104+
.setParameter('id=1')
105+
.setParameters({ first_name: 'Dara' })
106+
.all()
107+
expect(data).toEqual(items)
108+
})
77109
it('it should be able to remove parameter(s)', async () => {
78110
const items = [
79111
{ first_name: 'Dara', last_name: 'Hok', id: 1 },

src/__tests__/validator.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ describe('Validator', () => {
55
let validator: ValidatorType
66
beforeEach(() => {
77
validator = Validator
8+
validator.flush()
89
})
910
afterEach(() => {
1011
validator.flush()
@@ -13,6 +14,10 @@ describe('Validator', () => {
1314
validator.add('name', 'The name field is required.')
1415
expect(validator.any()).toBeTruthy()
1516
})
17+
test('add error with missed attribute', () => {
18+
validator.add('name-3diidi', 'The name field is required.')
19+
expect(validator.any()).toBeTruthy()
20+
})
1621
test('Add an error message as string', () => {
1722
const errors = {
1823
name: 'The name field is required.',
@@ -150,6 +155,16 @@ describe('Validator', () => {
150155
})
151156
})
152157

158+
it('should return empty object, with returnObject property is true', () => {
159+
const errors = {
160+
first_name: ['This field is required'],
161+
last_name: ['This field is required'],
162+
age: ['This field is required'],
163+
}
164+
validator.fill(errors)
165+
expect(validator.any([], true)).toEqual({})
166+
})
167+
153168
it('can pass array of keys to any method and get back boolean', () => {
154169
const errors = {
155170
first_name: ['This field is required'],

src/core/BaseProxy.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import type { AxiosError, AxiosInstance, AxiosResponse, Method } from 'axios'
2-
import { isFile } from '../util/objects'
2+
import { isFile, isArray } from '../util/objects'
33
import type { Errors } from '../'
44
import Validator from './Validator'
55
import { objectToFormData } from '../util/formData'
66

77
const validator = Validator
8+
const UNPROCESSABLE_ENTITY = 422
9+
export interface ParametersType {
10+
[key: string]: any
11+
}
812

913
class BaseProxy {
1014
public errors: Errors
@@ -68,16 +72,16 @@ class BaseProxy {
6872
this.$http[requestType](this.__getParameterString(url), data)
6973
.then((response: AxiosResponse) => {
7074
this.onSuccess()
71-
const { data = {} } = response
75+
const { data } = response
7276
resolve(data)
7377
})
7478
.catch((error: AxiosError) => {
7579
this.errors.processing = false
7680
validator.processing = false
7781
const { response } = error
7882
if (response) {
79-
const { data = {}, status } = response
80-
if (status === 422) {
83+
const { data, status } = response
84+
if (status === UNPROCESSABLE_ENTITY) {
8185
const errors = {}
8286
Object.assign(errors, data[this.$errorsKeyName])
8387
this.onFail(errors)
@@ -99,6 +103,16 @@ class BaseProxy {
99103
return parameters.length === 0 ? url : `${url}?${parameters.join('&')}`
100104
}
101105

106+
__getQueryString(parameter: string): string[] {
107+
const queries: string[] = parameter.split('&')
108+
const obj: any = {}
109+
queries.forEach(function (property: string) {
110+
const [key = null, value = null]: string[] = property.split('=')
111+
obj[key] = value
112+
})
113+
return obj
114+
}
115+
102116
__validateRequestType(requestType: Method): void {
103117
const requestTypes: Array<string> = [
104118
'get',
@@ -146,7 +160,7 @@ class BaseProxy {
146160
}
147161
}
148162

149-
if (Array.isArray(object)) {
163+
if (isArray(object)) {
150164
for (const key in object) {
151165
if (object.hasOwnProperty(key)) {
152166
return this.__hasFilesDeep(object[key])
@@ -164,7 +178,11 @@ class BaseProxy {
164178
return this
165179
}
166180

167-
setParameter(parameter: any, value: any): this {
181+
setParameter(parameter: string, value?: any): this {
182+
if (!value) {
183+
this.parameters = this.__getQueryString(parameter)
184+
return this
185+
}
168186
this.parameters[parameter] = value
169187
return this
170188
}
@@ -210,7 +228,3 @@ class BaseProxy {
210228
}
211229

212230
export default BaseProxy
213-
214-
export interface ParametersType {
215-
[key: string]: any
216-
}

src/core/BaseTransformer.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import snakeCaseKeys from 'snakecase-keys'
22
import camelcaseKeys from 'camelcase-keys'
33

4+
export type Attribute = {
5+
[key in string | number]: any
6+
}
7+
48
class BaseTransformer {
59
static fetchCollection(
610
items: Array<Attribute>,
@@ -32,7 +36,3 @@ class BaseTransformer {
3236
}
3337

3438
export default BaseTransformer
35-
36-
export type Attribute = {
37-
[key in string | number]: any
38-
}

src/core/Validator.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { is } from '../util/objects'
1+
import { is, isArray } from '../util/objects'
22

33
class Validator {
44
public errors: any
@@ -21,7 +21,7 @@ class Validator {
2121
}
2222

2323
has(field: any | any[]): boolean {
24-
if (field instanceof Array) {
24+
if (isArray(field)) {
2525
return is(Object.keys(this.errors), field)
2626
}
2727
let hasError = this.errors.hasOwnProperty(field)
@@ -46,12 +46,12 @@ class Validator {
4646
return this.get(field)[0]
4747
}
4848

49-
missed(field = null): boolean {
49+
missed(field?: string | string[]): boolean {
5050
return !this.has(field)
5151
}
5252

53-
nullState(field = null): boolean | null {
54-
return this.has(field) ? !this.has(field) : null
53+
nullState(field?: string | string[]): boolean | null {
54+
return this.has(field) ? this.missed(field) : null
5555
}
5656

5757
any(fields = [], returnObject?: boolean): boolean | string[] | any {

src/util/objects.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ export function isFile(object: any): boolean {
1414
return object instanceof File || object instanceof FileList
1515
}
1616

17-
export function merge(a: string | any, b: string | any): void {
17+
export function merge(a: any, b: any): string[] {
1818
for (const key in b) {
1919
if (!b.hasOwnProperty(key)) {
2020
continue
2121
}
2222
a[key] = cloneDeep(b[key])
2323
}
24+
return a
2425
}
2526

2627
export function cloneDeep(object: any): any {

yarn.lock

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3239,6 +3239,13 @@ axios@^0.20.0:
32393239
dependencies:
32403240
follow-redirects "^1.10.0"
32413241

3242+
axios@^0.21.1:
3243+
version "0.21.1"
3244+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
3245+
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
3246+
dependencies:
3247+
follow-redirects "^1.10.0"
3248+
32423249
babel-eslint@^10.1.0:
32433250
version "10.1.0"
32443251
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232"
@@ -13813,9 +13820,9 @@ vm-browserify@^1.0.1:
1381313820
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
1381413821

1381513822
"vue-api-queries@file:.":
13816-
version "0.0.10-alpha.1"
13823+
version "0.0.12"
1381713824
dependencies:
13818-
axios "^0.20.0"
13825+
axios "^0.21.1"
1381913826
camelcase-keys "^6.2.2"
1382013827
escape-string-regexp "^4.0.0"
1382113828
lodash.merge "^4.6.2"

0 commit comments

Comments
 (0)