From 323713382f1565ff8617ede08fdc8ed31ac3a594 Mon Sep 17 00:00:00 2001 From: Ghislain B Date: Thu, 1 Oct 2020 15:38:10 -0400 Subject: [PATCH] fix(select): make a collection array copy to avoid change by ref (#135) * fix(select): make a collection array copy to avoid change by ref - when using "addBlankEntry" or "addCustomFirstEntry", the SelectFilter was affecting SelectEditor (and vice versa) because the collection was used by ref, so to fix this we can just do a copy of the collection before dealing with it --- packages/common/src/editors/selectEditor.ts | 22 +++++++++++++-------- packages/common/src/filters/selectFilter.ts | 14 +++++++++---- test/cypress.json | 4 ++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/common/src/editors/selectEditor.ts b/packages/common/src/editors/selectEditor.ts index bf6475663..5c9e5dc78 100644 --- a/packages/common/src/editors/selectEditor.ts +++ b/packages/common/src/editors/selectEditor.ts @@ -190,7 +190,7 @@ export class SelectEditor implements Editor { // collection of strings, just return the filtered string that are equals if (this.collection.every(x => typeof x === 'string')) { - return this.collection.filter(c => elmValue.indexOf(c.toString()) !== -1); + return this.collection.filter(c => elmValue.indexOf(c?.toString()) !== -1); } // collection of label/value pair @@ -198,7 +198,7 @@ export class SelectEditor implements Editor { const isIncludingPrefixSuffix = this.collectionOptions && this.collectionOptions.includePrefixSuffixToSelectedValues || false; return this.collection - .filter(c => elmValue.indexOf(c.hasOwnProperty(this.valueName) && c[this.valueName].toString()) !== -1) + .filter(c => elmValue.indexOf(c.hasOwnProperty(this.valueName) && c[this.valueName]?.toString()) !== -1) .map(c => { const labelText = c[this.valueName]; let prefixText = c[this.labelPrefixName] || ''; @@ -235,13 +235,13 @@ export class SelectEditor implements Editor { if (fieldName !== undefined) { // collection of strings, just return the filtered string that are equals if (this.collection.every(x => typeof x === 'string')) { - return findOrDefault(this.collection, (c: any) => c.toString() === elmValue); + return findOrDefault(this.collection, (c: any) => c?.toString() === elmValue); } // collection of label/value pair const separatorBetweenLabels = this.collectionOptions && this.collectionOptions.separatorBetweenTextLabels || ''; const isIncludingPrefixSuffix = this.collectionOptions && this.collectionOptions.includePrefixSuffixToSelectedValues || false; - const itemFound = findOrDefault(this.collection, (c: any) => c.hasOwnProperty(this.valueName) && c[this.valueName].toString() === elmValue); + const itemFound = findOrDefault(this.collection, (c: any) => c.hasOwnProperty(this.valueName) && c[this.valueName]?.toString() === elmValue); // is the field a complex object, "address.streetNumber" const isComplexObject = fieldName?.indexOf('.') > 0; @@ -559,15 +559,21 @@ export class SelectEditor implements Editor { return outputCollection; } - renderDomElement(collection: any[]) { - if (!Array.isArray(collection) && this.collectionOptions?.collectionInsideObjectProperty) { + renderDomElement(inputCollection: any[]) { + if (!Array.isArray(inputCollection) && this.collectionOptions?.collectionInsideObjectProperty) { const collectionInsideObjectProperty = this.collectionOptions.collectionInsideObjectProperty; - collection = getDescendantProperty(collection, collectionInsideObjectProperty); + inputCollection = getDescendantProperty(inputCollection, collectionInsideObjectProperty); } - if (!Array.isArray(collection)) { + if (!Array.isArray(inputCollection)) { throw new Error('The "collection" passed to the Select Editor is not a valid array.'); } + // make a copy of the collection so that we don't impact SelectFilter, this could happen when calling "addBlankEntry" or "addCustomFirstEntry" + let collection: any[] = []; + if (inputCollection.length > 0) { + collection = [...inputCollection]; + } + // user can optionally add a blank entry at the beginning of the collection // make sure however that it wasn't added more than once if (this.collectionOptions?.addBlankEntry && Array.isArray(collection) && collection.length > 0 && collection[0][this.valueName] !== '') { diff --git a/packages/common/src/filters/selectFilter.ts b/packages/common/src/filters/selectFilter.ts index 2e70eefee..296758aee 100644 --- a/packages/common/src/filters/selectFilter.ts +++ b/packages/common/src/filters/selectFilter.ts @@ -243,15 +243,21 @@ export class SelectFilter implements Filter { return outputCollection; } - renderDomElement(collection: any[]) { - if (!Array.isArray(collection) && this.collectionOptions?.collectionInsideObjectProperty) { + renderDomElement(inputCollection: any[]) { + if (!Array.isArray(inputCollection) && this.collectionOptions?.collectionInsideObjectProperty) { const collectionInsideObjectProperty = this.collectionOptions.collectionInsideObjectProperty; - collection = getDescendantProperty(collection, collectionInsideObjectProperty || ''); + inputCollection = getDescendantProperty(inputCollection, collectionInsideObjectProperty || ''); } - if (!Array.isArray(collection)) { + if (!Array.isArray(inputCollection)) { throw new Error('The "collection" passed to the Select Filter is not a valid array.'); } + // make a copy of the collection so that we don't impact SelectEditor, this could happen when calling "addBlankEntry" or "addCustomFirstEntry" + let collection: any[] = []; + if (inputCollection.length > 0) { + collection = [...inputCollection]; + } + // user can optionally add a blank entry at the beginning of the collection // make sure however that it wasn't added more than once if (this.collectionOptions?.addBlankEntry && Array.isArray(collection) && collection.length > 0 && collection[0][this.valueName] !== '') { diff --git a/test/cypress.json b/test/cypress.json index 9dfd3a0d6..7204f294c 100644 --- a/test/cypress.json +++ b/test/cypress.json @@ -12,5 +12,5 @@ "supportFile": "test/cypress/support/index.js", "videosFolder": "test/cypress/videos", "defaultCommandTimeout": 5000, - "pageLoadTimeout": 30000 -} \ No newline at end of file + "pageLoadTimeout": 60000 +}