import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; import { URLSearchParams } from '@angular/http'; import { Defaults } from '../constant/defaults.constant'; export class Helper { static merge(component: any, config: any) { Object.keys(config).forEach(key => { if (config[key] !== null && config[key] !== undefined) { component[key] = config[key]; } }); } static atLeastOneRequired(fa: FormArray) { return fa.value.length ? null : { required: true }; } static buildFormGroup(questions: any, responses = {}){ if (!responses) responses = {}; return new FormGroup(this.generateFormGroup(questions, responses)); } static generateFormGroup(questions, responses) { return Object.assign({}, ...this.groupToQuestions(questions, responses)); } static groupToQuestions(questions, responses = {}, required = false, isIterable?:boolean) { return questions.map(question => { let object = {}; if (question.type === "group") { // If block - required only for groups within iterable component if (isIterable) { object[question.key] = this.groupToIterable(question, responses); } else { // Else block - required for all groups other than the groups within iterable object[question.key] = new FormGroup(Object.assign({}, ...this.groupToQuestions(question.questions, responses[question.key], question.config ? question.config.required : null))); } } else if (question.type === "checkbox") { if (responses && !this.isEmptyObject(responses) && responses[question.key]) { const responseControls = responses[question.key].map((res) => { const obj = {}; obj['name'] = res['name']; obj['completed'] = res['completed']; return new FormControl(obj); }); object[question.key] = new FormArray(responseControls); } else { object[question.key] = new FormArray([]); } } else if (question.type === "iterable") { let obj = this.groupToQuestions(question.config.questions, responses, question.config ? question.config.required : null, true); obj = Object.assign({}, ...obj); object[question.key] = obj[question.key]; } else if (question.type === "multi-input") { let controls:any[] = question.questions.filter((q) => q.key); object[question.key] = this.groupToArray(controls); } else { // TODO: Apply responses to other question types if (question.key) { const response = responses[question.key] !== undefined ? responses[question.key] : ''; if (required || question.config.required) { object[question.key] = new FormControl(response, Validators.required); } else { object[question.key] = new FormControl(response); } } } return object; }); } static groupToIterable(question, responses) { const response = responses[question.key]; const questionList = question.questions; let iterables:FormArray = new FormArray([]); if (response && response[Defaults.ITERABLE_KEY] && response[Defaults.ITERABLE_KEY] instanceof Array && response[Defaults.ITERABLE_KEY].length) { response[Defaults.ITERABLE_KEY].forEach(res => { let fg = new FormGroup(Object.assign({}, ...this.groupToQuestions(questionList, res, question.config ? question.config.required : null))); iterables.push(fg); }); } let newGroup = {}; newGroup[Defaults.ITERABLE_KEY] = iterables; return new FormGroup(newGroup); } static groupToControls(controls) { return controls.map(control => { let object = {}; object[control] = new FormControl(); return object; }); } static groupToArray(controls) { return new FormArray([new FormGroup(Object.assign({}, ...this.groupToControls(controls)))]); } static normalizeDataSource(dataSource, displayKey) { if (Helper.isArrayOfObject(dataSource, displayKey)) { return (dataSource).map((key) => key[displayKey]); } else if (Array.isArray(dataSource) && typeof dataSource[0] === 'string') { return dataSource; } else { console.warn('Please provide dataSource with array of string for typeahead value.'); return []; } } // Todo if not used, can be removed static mapToSearchParams(search: any) { const params = new URLSearchParams(); Object.keys(search).map(key => params.set(key, search[key])); return params; } static isArrayOfObject(data, displayKey) { return data && data[0] && typeof data[0] === 'object' && typeof data[0][displayKey] === 'string'; } static displayRequiredError(fc: FormControl) { return fc ? fc.touched && fc.errors : false; } static findLabel(displayKey, valueKey, options) { return (value) => { return (options.find(option => option[valueKey] === value))[displayKey]; }; } static isObject(obj: any) { return obj instanceof Object; } static isArray(obj: any) { return Array.isArray(obj); } static isEmptyObject(obj: {}) { return Object.keys(obj).every((key) => this.isObject(obj[key]) ? this.isEmptyObject(obj[key]) : !obj[key]); } static isInputUnit(obj: any) { return Object.keys(obj).length === 2 && Object.keys(obj).reduce(function (previous, current) { return previous && (current === 'inputText' || current === 'units'); }, true); } static valueOfInputUnit(obj: any) { if(obj && obj['inputText'] && obj['units'] &&this.isInputUnit(obj)) { return obj['inputText'].toString().concat(' ', obj['units'].label); } return ''; } static showErrors(formGroup, includeIterableValidation?) { for (const questionSection in formGroup.controls) { if (formGroup.controls.hasOwnProperty(questionSection)) { for (const question in formGroup.controls[questionSection]['controls']) { formGroup.controls[questionSection]['controls'][question].markAsTouched({onlySelf: true}); // For iterables if(includeIterableValidation) { Helper._showIterableErrors(formGroup, questionSection, question); } } } } } static _showIterableErrors(formGroup, questionSection, question) { if (formGroup.controls[questionSection]['controls'][question] && formGroup.controls[questionSection]['controls'][question].value && formGroup.controls[questionSection]['controls'][question].value[Defaults.ITERABLE_KEY] && formGroup.controls[questionSection]['controls'][question].value[Defaults.ITERABLE_KEY].length === 0) { formGroup.controls[questionSection]['controls'][question]['controls'][Defaults.ITERABLE_KEY].setErrors(Validators.min); } } }