diff --git a/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java b/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java index baf14718a..e9938a5ff 100644 --- a/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java +++ b/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java @@ -19,9 +19,9 @@ public abstract class AbstractBatchLogger { private Map concurrentHashMap = new ConcurrentHashMap(); public AbstractBatchLogger(Environment environment) { - //ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); - //executor.scheduleAtFixedRate(() -> this.outputData(), Long.parseLong(environment.getProperty("http-logger.initial-delay")), Long.parseLong(environment.getProperty("http-logger.delay")), TimeUnit.SECONDS); + executor.scheduleAtFixedRate(() -> this.outputData(), Long.parseLong(environment.getProperty("http-logger.initial-delay")), Long.parseLong(environment.getProperty("http-logger.delay")), TimeUnit.SECONDS); } public abstract LoggingOutputType logOutputType(); diff --git a/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.ts index cca8b26a5..bdd85d451 100644 --- a/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.ts @@ -15,7 +15,7 @@ import { ExternalSourcesService } from '../../services/external-sources/external import { DatasetWizardService } from '../../services/dataset-wizard/dataset-wizard.service'; import { TranslateService } from '@ngx-translate/core'; import { ActivatedRoute, Router, Params } from '@angular/router'; -import { Component, ViewChild, OnInit, AfterViewInit, ViewEncapsulation, TemplateRef } from "@angular/core"; +import { Component, ViewChild, OnInit, AfterViewInit, ViewEncapsulation, TemplateRef, ChangeDetectionStrategy } from "@angular/core"; import { FormGroup, Validators, FormBuilder, FormArray } from "@angular/forms"; import * as FileSaver from 'file-saver'; import { MatPaginator, MatSort, MatSnackBar, MatStepper, MatDialog } from "@angular/material"; @@ -46,7 +46,7 @@ import { ServicesReferencedModelHelperComponent } from '../dataset-referenced-mo selector: 'app-dataset-wizard-component', templateUrl: 'dataset-wizard.component.html', styleUrls: ['./dataset-wizard.component.scss'], - encapsulation: ViewEncapsulation.None + encapsulation: ViewEncapsulation.None, }) export class DatasetWizardComponent implements OnInit, IBreadCrumbComponent { breadCrumbs: Observable; diff --git a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html index 7e5d6a7c1..f00a4be02 100644 --- a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html +++ b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts index e4b9666ca..1ddfc34a3 100644 --- a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts +++ b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts @@ -1,8 +1,9 @@ import { Field } from '../../models/Field'; -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core'; import { FormGroup, ValidatorFn, AbstractControl, Validators } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { VisibilityRulesService } from '../../utilities/visibility-rules/visibility-rules.service'; +import { Subscription } from 'rxjs'; @Component({ @@ -12,20 +13,25 @@ import { VisibilityRulesService } from '../../utilities/visibility-rules/visibil styleUrls: [ './dynamic-form-field.component.css' ], - encapsulation: ViewEncapsulation.None }) export class DynamicFormFieldComponent implements OnInit { @Input() field: Field; - @Input() form: FormGroup; + form: FormGroup; @Input() pathName: string; @Input() path: string; + change: Subscription; + trackByFn = (index,item) => item["id"] + constructor(private route: ActivatedRoute, public visibilityRulesService: VisibilityRulesService) { - constructor(private route: ActivatedRoute, public visibilityRulesService: VisibilityRulesService) { } + } ngOnInit() { - this.form.get('value').valueChanges.subscribe(item => { + this.form = this.visibilityRulesService.getFormGroup(this.field.id) + if(!this.form) debugger; + if(!this.form.get('value')) debugger; + this.change = this.form.get('value').valueChanges.subscribe(item => { this.visibilityRulesService.updateValueAndVisibility(this.field.id) }) } @@ -34,6 +40,12 @@ export class DynamicFormFieldComponent implements OnInit { } + ngOnDestroy(): void { + //Called once, before the instance is destroyed. + //Add 'implements OnDestroy' to the class. + this.change.unsubscribe() + } + clearInput() { } diff --git a/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.html b/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.html index 909f688d2..ce3c6d70a 100644 --- a/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.html +++ b/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.html @@ -1,4 +1,4 @@ -
+
{{compositeField.title}}
@@ -7,7 +7,7 @@
{{compositeField.extendedDescription}}
-
@@ -20,8 +20,8 @@
{{compositeField.extendedDescription}}
- \ No newline at end of file +
diff --git a/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.ts b/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.ts index 02cddeadd..f50a16894 100644 --- a/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.ts +++ b/dmp-frontend/src/app/form/dynamic-form-composite-field/dynamic-form-composite-field.ts @@ -1,7 +1,7 @@ import { VisibilityRulesService } from '../../utilities/visibility-rules/visibility-rules.service'; import { CompositeField } from '../../models/CompositeField'; import { FormGroup, FormArray } from '@angular/forms'; -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core'; import { Field } from '../../models/Field'; @Component({ selector: 'df-composite-field', @@ -14,15 +14,19 @@ import { Field } from '../../models/Field'; export class DynamicFormCompositeFieldComponent implements OnInit { @Input() compositeField: CompositeField - @Input() form: FormGroup; + form: FormGroup; @Input() pathName: string; @Input() path: string; + trackByFn = (index, item) => item["id"] - constructor(private visibilityRulesService: VisibilityRulesService) { } + constructor(private visibilityRulesService: VisibilityRulesService) { + } ngOnInit() { + this.form = this.visibilityRulesService.getFormGroup(this.compositeField.id) } + addMultipleField(fieldIndex: number) { let field: Field = this.compositeField.fields[fieldIndex].cloneForMultiplicity(fieldIndex, ""); this.compositeField.fields[fieldIndex].multiplicityItems.push(field); diff --git a/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.html b/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.html index bab9a0d3c..b7c88206c 100644 --- a/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.html +++ b/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.html @@ -1,19 +1,19 @@ -
+
- diff --git a/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts b/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts index e837706a9..21ef6f52f 100644 --- a/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts +++ b/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts @@ -1,6 +1,6 @@ import { VisibilityRulesService } from '../../utilities/visibility-rules/visibility-rules.service'; import { FieldGroup } from '../../models/FieldGroup'; -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core'; import { FormGroup, Validators, FormControl, FormArray } from '@angular/forms'; import { NgForm } from '@angular/forms'; import { CompositeField } from '../../models/CompositeField'; @@ -15,31 +15,16 @@ import { CompositeField } from '../../models/CompositeField'; }) export class DynamicFormGroupComponent implements OnInit { @Input() group: FieldGroup - @Input() form: FormGroup; + form: FormGroup; @Input() pathName: string; @Input() path: string; - - + trackByFn = (index,item) => item["id"] constructor(public visibilityRulesService: VisibilityRulesService) { } ngOnInit() { - //let st = this.group.style == "any" ? "" : this.group.style; - //this.classFromJson = this.group.class == "" ? "" : this.group.class; - - /* this.customStyle = {}; - if (st != "") { - st.replace(/"/g, '\\"'); - - var attributes = st.split(';'); - for (var i = 0; i < attributes.length; i++) { - var entry = attributes[i].split(':'); - entry[1].replace(/["]/g, " "); - //this.customStyle[entry[0]] = '2px solid #c1baba'; - var a = entry[0]; - this.customStyle[a] = entry[1]; - } */ + this.form = this.visibilityRulesService.getFormGroup(this.group.id) } @@ -50,29 +35,7 @@ export class DynamicFormGroupComponent implements OnInit { } addFieldSet() { - /* debugger; - let subgroup: any = {}; - this.group.compositeFields.groupFields.forEach((field, i) => { - debugger; - this.form.addControl(field.key + "_" + i, new FormControl("")) - if (field.controlType == "textbox") { - let newfield: FieldBase; - let rule = new Rule(); - newfield = new TextboxField({ - label: field.label + "_" + i, - key: field.key + "_" + i, - value: "", - order: field.order, - rules: field.rules, - visible: field.visible, - group: field.group, - description: field.description - }); - this.group.compositeFields.groupFields.push(newfield) - } - - }); */ } } diff --git a/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.html b/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.html index a238ea2f7..1dcf545b6 100644 --- a/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.html +++ b/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.html @@ -1,4 +1,4 @@ -
+
@@ -7,20 +7,20 @@

{{section.description}}

-

{{section.extendedDescription}}

+
-
-
+
+
- -
- +
+
@@ -34,9 +34,9 @@
- +
-
\ No newline at end of file +
diff --git a/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts b/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts index f04828950..970deec8d 100644 --- a/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts +++ b/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts @@ -1,6 +1,6 @@ import { VisibilityRulesService } from '../../utilities/visibility-rules/visibility-rules.service'; import { FormGroup, Form, FormArray } from '@angular/forms'; -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core'; import { CompositeField } from '../../models/CompositeField'; import { Section } from '../../models/Section'; @@ -16,12 +16,14 @@ import { Section } from '../../models/Section'; export class DynamicFormSectionComponent implements OnInit { @Input() section: Section - @Input() form: FormGroup; + form: FormGroup; @Input() pathName: string; @Input() path: string; + trackByFn = (item) => item["id"] constructor(public visibilityRulesService: VisibilityRulesService) { } ngOnInit() { + this.form = this.visibilityRulesService.getFormGroup(this.section.id) } addMultipleField(fieldsetIndex: number) { @@ -31,9 +33,9 @@ export class DynamicFormSectionComponent implements OnInit { } isVisible(pathname: string, fieldSet: CompositeField): boolean { - if (!this.visibilityRulesService.isElementVisible(pathname, fieldSet.id)) return false; + if (!fieldSet || !this.visibilityRulesService.getFormGroup(fieldSet.id)) return false; for (var i = 0; i < fieldSet.fields.length; i++) { - if (this.visibilityRulesService.isElementVisible(pathname + '.fields.' + i, fieldSet.fields[i].id)) + if (this.visibilityRulesService.getFormGroup(fieldSet.fields[i].id)) return true; } return false; diff --git a/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.html b/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.html index e98248d79..bf9b7237a 100644 --- a/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.html +++ b/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.html @@ -1,47 +1,44 @@ 
- - + - - -
- + + + -
-
- - -
-
+
+
+ + +
+
-
- - -
-
- - {{page.title}} -
- - -
-
-
-
-
- + +
+
+ + {{page.title}} +
+ +
+
+
+
+
+ -
-
-
diff --git a/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.ts b/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.ts index a27e6c426..527ea332f 100644 --- a/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.ts +++ b/dmp-frontend/src/app/form/dynamic-form/dynamic-form.component.ts @@ -6,7 +6,7 @@ import { BaseHttpService } from '../../utilities/cite-http-service-module/base-h import { VisibilityRulesService } from '../../utilities/visibility-rules/visibility-rules.service'; import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel'; import { DatasetWizardModel } from '../../models/datasets/DatasetWizardModel'; -import { Component, Input, OnInit, AfterViewChecked, ViewChild, forwardRef, ViewEncapsulation } from '@angular/core'; +import { Component, Input, OnInit, AfterViewChecked, ViewChild, forwardRef, ViewEncapsulation, AfterViewInit, ChangeDetectionStrategy } from '@angular/core'; import { FormGroup, Validators, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NgForm } from '@angular/forms'; import { Router, ActivatedRoute, ParamMap, Params } from '@angular/router'; @@ -28,10 +28,13 @@ declare function simple_notifier(type: string, title: string, message: string): }) export class DynamicFormComponent implements OnInit { + @Input() dataModel: DatasetWizardModel = new DatasetWizardModel(); @Input() path: string; @Input() form: FormGroup; id: string; + trackByFn = (index,item) => item["id"] + pageTrackByFn = (index,item) => item["id"] // @Input() datasetId: string; pathName: string; @@ -64,6 +67,7 @@ export class DynamicFormComponent implements OnInit { this.visibilityRulesService.formGroup = this.form; this.visibilityRulesService.buildVisibilityRules(rules) this.datasetProfileDefinitionModel = this.dataModel.datasetProfileDefinition + this.visibilityRulesService.setModel(this.datasetProfileDefinitionModel) this.createPagination(); this.progressbar = true; @@ -78,6 +82,7 @@ export class DynamicFormComponent implements OnInit { }); } + toggleSidebar() { this.visibleSidebar = !this.visibleSidebar; } diff --git a/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts b/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts index cb4ca2f2e..287205057 100644 --- a/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts +++ b/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts @@ -57,12 +57,12 @@ export class ProgressBarComponent implements OnInit { else if (control instanceof FormArray) { let formArray = (control); for (let i = 0; i < formArray.length; i++) { - if (formArray.get("" + i).value && this.visibilityRulesService.isElementVisible(null, formArray.get("" + i).value.id)) - value += this.getFormControlDepthLength(formArray.get("" + i)) + //if (formArray.get("" + i).value && this.visibilityRulesService.isElementVisible(null, formArray.get("" + i).value.id)) + //value += this.getFormControlDepthLength(formArray.get("" + i)) } } - else if (key === "value" && this.visibilityRulesService.isElementVisible(null, form.controls["id"].value)) - value++; + //else if (key === "value" && this.visibilityRulesService.isElementVisible(null, form.controls["id"].value)) + //value++; }); return value; } diff --git a/dmp-frontend/src/app/utilities/JsonSerializer.ts b/dmp-frontend/src/app/utilities/JsonSerializer.ts index dbb28b1c5..705a7eee1 100644 --- a/dmp-frontend/src/app/utilities/JsonSerializer.ts +++ b/dmp-frontend/src/app/utilities/JsonSerializer.ts @@ -1,17 +1,22 @@ import { Serializable } from '../models/interfaces/Serializable'; export class JsonSerializer { - public static fromJSONArray>(items: any[], type: { new(): T; }): T[] { - if (!items) return new Array(); - const objectList: T[] = new Array(); - for (let i = 0; i < items.length; i++) { - objectList.push(new type().fromJSONObject(items[i])) - } - return objectList; + public static fromJSONArray>(items: any[], type: { new(): T; }): T[] { + if (!items) return new Array(); + const objectList: T[] = new Array(); + for (let i = 0; i < items.length; i++) { + objectList.push(new type().fromJSONObject(items[i])) } + return objectList; + } - public static fromJSONObject>(item: any, type: { new(): T; }): T { - if (!item) return null; - return new type().fromJSONObject(item); - } -} \ No newline at end of file + public static fromJSONObject>(item: any, type: { new(): T; }): T { + if (!item) return null; + return new type().fromJSONObject(item); + } + + public static copy>(item: any, itemToCopy: any): T { + if (!item) return null; + return item.fromJSONObject(itemToCopy); + } +} diff --git a/dmp-frontend/src/app/utilities/visibility-rules/visibility-rules.service.ts b/dmp-frontend/src/app/utilities/visibility-rules/visibility-rules.service.ts index 4959f0f1a..8438f03c4 100644 --- a/dmp-frontend/src/app/utilities/visibility-rules/visibility-rules.service.ts +++ b/dmp-frontend/src/app/utilities/visibility-rules/visibility-rules.service.ts @@ -1,8 +1,10 @@ import { VisibilityRule } from './models/VisibilityRule'; import { VisibilityRulesContext } from './models/VisibilityRulesContext'; import { FormGroup } from '@angular/forms'; -import { Injectable } from '@angular/core'; +import { Injectable, ApplicationRef, NgZone } from '@angular/core'; import { Rule } from '../../models/Rule'; +import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel'; +import { JsonSerializer } from '../JsonSerializer'; @Injectable() export class VisibilityRulesService { @@ -10,17 +12,27 @@ export class VisibilityRulesService { public visibilityRuleContext: VisibilityRulesContext; public fieldsPathMemory: any = {}; private elementVisibilityMap = new Map(); + private initialModel: DatasetProfileDefinitionModel; + private currentModel: DatasetProfileDefinitionModel; - public isElementVisible(pathKey: string, id: string) { + constructor(public applicationReference: ApplicationRef, public ngZone: NgZone) { + + } + + public setModel(model: DatasetProfileDefinitionModel) { + this.initialModel = JsonSerializer.fromJSONObject(model, DatasetProfileDefinitionModel); + this.currentModel = model + this.visibilityRuleContext.rules.forEach(item => this.evaluateVisibility(item)) + + } + + public getFormGroup(id: string): FormGroup { + let pathKeyArray = this.search("pages", this.initialModel.pages, id).split(".") + + pathKeyArray.pop(); + let pathKey = pathKeyArray.join("."); if (!this.fieldsPathMemory[id] && pathKey) this.fieldsPathMemory[id] = pathKey; - if (pathKey && this.visibilityRuleContext.getRulesFromKey(id)) this.evaluateVisibility(this.visibilityRuleContext.getRulesFromKey(id)) - - if (this.checkElementVisibility(id)) { - return true - } else { - this.clearValues(pathKey) - return false; - } + return (this.formGroup.get(pathKey)); } public checkElementVisibility(id: string): boolean { @@ -44,16 +56,25 @@ export class VisibilityRulesService { if (this.formGroup.get(pathKey + '.value') && ((this.formGroup.get(pathKey + '.value').value == null || this.formGroup.get(pathKey + '.value').value == undefined) || "" + this.formGroup.get(pathKey + '.value').value != "" + visibilityRule.sourceVisibilityRules[i].sourceControlValue)) { if (this.formGroup.get(pathKey).parent.get("id")) { if (!this.checkElementVisibility(this.formGroup.get(pathKey).parent.get("id").value)) { + let targetPathKey = this.fieldsPathMemory[visibilityRule.targetControlId] + this.getObject(this.currentModel, "id", visibilityRule.targetControlId, this.currentModel, true) this.elementVisibilityMap.set(visibilityRule.targetControlId, false) + this.clearValues(targetPathKey) return; } } else { + let targetPathKey = this.fieldsPathMemory[visibilityRule.targetControlId] + this.getObject(this.currentModel, "id", visibilityRule.targetControlId, this.currentModel, true) this.elementVisibilityMap.set(visibilityRule.targetControlId, false) + this.clearValues(targetPathKey) return; } } } + let obj = this.getObject(this.initialModel, "id", visibilityRule.targetControlId, this.initialModel) + let targetObjPathKey = this.fieldsPathMemory[visibilityRule.targetControlId] ? this.fieldsPathMemory[visibilityRule.targetControlId] : this.search("pages", this.initialModel.pages, obj); + this.updateValue(this.currentModel, obj, targetObjPathKey) this.elementVisibilityMap.set(visibilityRule.targetControlId, true) } @@ -67,6 +88,61 @@ export class VisibilityRulesService { for (var i = 0; i < this.formGroup.get(pathKey)["controls"].fields.length; i++) this.clearValues(pathKey + '.fields.' + i); } + } + // deleteFromModel(path: string, obj: any) { + // if (!path) return + // const _obj = JSON.parse(JSON.stringify(obj)); + // const keys = path.split('.'); + + // keys.reduce((acc, key, index) => { + // if (index === keys.length - 1) { + // delete acc[key]; + // return true; + // } + // return acc[key]; + // }, _obj); + // return _obj; + // } + + updateValue(obj, value, path) { + var i; + if (value['id'].targetControlId === "other216a") debugger; + path = path.split('.'); + for (i = 0; i < path.length - 1; i++) + obj = obj[path[i]]; + + for (let propIndex = 0; propIndex < obj.length; propIndex++) { + if (obj[propIndex]["id"] === value["id"]) return + } + obj.splice(path[i], 0, value); + } + + search(path, obj, target) { + for (var k in obj) { + if (obj.hasOwnProperty(k)) + if (obj[k] === target) + return path + "." + k + else if (typeof obj[k] === "object") { + var result = this.search(path + "." + k, obj[k], target); + if (result) + return result; + } + } + return false; + } + + private getObject(obj, key, val, parent, deleteObj = false) { + for (var i in obj) { + if (!obj.hasOwnProperty(i)) continue; + if (typeof obj[i] == 'object') { + let returnObj = this.getObject(obj[i], key, val, obj, deleteObj); + if (returnObj) return returnObj + } else if (i == key && obj[key] == val) { + //console.log(obj[key]) + if (deleteObj) parent.splice(parent.indexOf(obj), 1); + return obj + } + } } }