· 6 years ago · Jan 13, 2020, 07:58 AM
1import api from "@/Api";
2import ValidationErrorInterface from "@/validation/ValidationErrorInterface";
3import ValidationFailureInterface from "@/validation/ValidationFailureInterface";
4
5export default class Form {
6 private readonly originalData: Object;
7 errorBag: ErrorBag;
8
9 constructor(data: Object) {
10 this.originalData = data;
11 for (let field in data) {
12 // @ts-ignore
13 this[field] = data[field];
14 }
15 this.errorBag = new ErrorBag();
16 }
17
18 submit(requestType: string, url: string): Promise<any> {
19 this.errorBag.clear();
20 return new Promise<any>((resolve, reject) => {
21 // @ts-ignore
22 api[requestType](url, this.data())
23 .then((response: { data: any; }) => {
24 resolve(response.data)
25 })
26 .catch((err: any) => {
27 if (err.response.status === 422) this.onFail(err.response.data);
28 if (err.response.status === 401) this.errorBag.setMessage(err.response.data.message)
29 reject(err.response.data);
30 })
31 })
32 }
33
34 load(obj: {}) {
35 Object.entries(obj).forEach(
36 ([key, value]) => {
37 // @ts-ignore
38 this[key] = value;
39 }
40 )
41 }
42
43 patch(url: string): Promise<any> {
44 return this.submit('patch', url);
45 }
46
47 post(url: string): Promise<any> {
48 return this.submit('post', url);
49 }
50
51 reset(): void {
52 for (let field in this.originalData) {
53 // @ts-ignore
54 this[field] = '';
55 }
56 this.errorBag.clear();
57 }
58
59 private data(): {} {
60 let data = {};
61 for (let property in this.originalData) {
62 // @ts-ignore
63 data[property] = this[property];
64 }
65 return data;
66 }
67
68 private static setFormData(data: {}): FormData {
69 let formData = new FormData();
70 for (let field in data) {
71 // @ts-ignore
72 formData.append(field, data[field]);
73 }
74 return formData;
75 }
76
77 private onFail(response: ValidationFailureInterface): void {
78 this.errorBag.record(response.errors);
79 this.errorBag.setMessage(response.message);
80 }
81}
82
83export class ErrorBag {
84 private errors: Array<ValidationErrorInterface>;
85 private message: string;
86
87 constructor() {
88 this.errors = [];
89 this.message = ''
90 }
91
92 get(field: string): string | null {
93 const error = this.errors.find(error => error.param === field);
94 if (error) return error.msg;
95 return null;
96 }
97
98 has(field: string): boolean {
99 return !!this.get(field);
100 }
101 isEmpty(): boolean {
102 return !this.errors.length
103 }
104
105 clear(field?: string): void {
106 if (!field) {
107 this.errors = [];
108 this.message = '';
109 return;
110 }
111
112 const error = this.errors.find(e => e.param === field);
113 if (error) this.errors.splice(this.errors.indexOf(error), 1);
114 if (this.isEmpty()) this.message = '';
115 }
116
117 record(errors: Array<ValidationErrorInterface>): void {
118 this.errors = errors
119 }
120
121 setMessage(message: string): void {
122 this.message = message;
123 }
124
125 getMessage(): string {
126 return this.message
127 }
128
129 hasMessage(): boolean {
130 return !!this.message
131 }
132}