Using latest releases of Angular and Ignite UI (12.0.3):
I have a pair of Dropdowns using the igx-input-group model. One of them determines the filtered data set of the second. I am using the (onSelection) attribute to filter the second, but I am also getting an error NG0100: ExpressionChangedAfterItHasBeenCheckedError.
The functionality isn't broken, but it's throwing an error like it is. If I didn't have tech savvy users who will complain, I wouldn't bother asking how to fix it.
A previous question suggested using markForCheck on the igx-grid component. Is there something similar for this setup I should be using, either on the dropdown or the input-group? This is in a dialog modal, if that makes any difference.
Hello Chris,
Thank you for contacting Infragistics Community!
In pursuit of reproducing the described behavior on my side I have created a small sample where the items of the second igxDropDown Component are assigned within the onSelection event hook of the first one and no exceptions are thrown.
In order to be able to assist you further could you please try to modify the provided sample so that it replicates the issue you are facing and send it back to me. Having a sample, which I can debug on my side, will be highly appreciated and extremely helpful for providing you with solution as soon as possible.
Looking forward to hearing from you.
Best Regards, Martin Evtimov Associate Software Developer Infragistics, Inc.
Martin,
There are a few possibilities for the cause here:
Here is a basic example of the data being presented for both lists:
public designs:{name:string, facilities:string, id:number}[] = []; //filled with back-end process public facilities:{name:string, id:number}[] = []; //filled with back-end process public filteredFacilities:{name:string, id:number}[] = []; //filled with filterFacilities below public newDf:{design:string, facility:string}; // built initially from designs[0], filteredFacilities[0]; filterFacilities(design:string) { this.filteredFacilities = this.facilities.filter(a => this.designs.filter(d => d.name == design)[0].facilities.indexOf(a.name) > -1); this.newDf.facility = this.filteredFacilities[0].name; this.newDf.facilityId = this.filteredFacilities[0].id; };
The [(ngModel)] for the dropdowns is the newDf (design for the design dropdown; facility for facility dropdown) and as mentioned, initial values are design[0] and filteredFacilities[0]. As design changes, filteredFacilities changes, but the first entry is always the initially selected value. This is because 90% of the time, the user will go with the first value in filteredFacilities.
The error happens when a Design is chosen that does not contain the previously selected value of the Facility dropdown.
Another issue I'm facing is that I am unable to concatenate for the initial display value of another dropdown that displays the list of available Design + Facility mappings:
public dfMappings: {design:string, facility:string, id:number}[] = []; //initialized by back-end process public fromMapping: {design:string, facility:string, id:number}; //initialized as dfMappings[0]
I have tried the below in initializing the input's view (note, once dropdown is opened, all dfMappings show as "<design> for <facility>":
I put the above as values for [value], using the (dropdown id) fromMap.selectedItem?.value notation for fromMapping and directly using fromMapping.
[(ngModel)]="fromMapping" and value passed to the input from the dropdown is a mapping of the same structure.
Thank you for getting back to me!
Following your description I have updated the provided sample so that:
As you can observe no exceptions are thrown when changing the selectedItem of both igxDropDown components. Please keep in mind that as I have already mentioned in my previous reply without being able to replicate the described issue and to debug it on my side it will be really difficult to provide you with solution. Having this in mind providing me with small isolated sample will be highly appreciated and extremely helpful.
PS. You have mentioned that you have used [(ngModel)]. After further investigation I can verify that the igxDropDown component class doesn’t inheritance the ControlValueAccessor interface meaning that the ngModel directive cannot be used together with it.
I’m glad that you have managed to achieve your requirements.
Thank you for using Infragistics Components!
That works, slightly differently than implemented (I used e.newValue !== undefined) to process new values.
Please note that currently, by design, the onSelection event is emitted when the selectedItem of the igxDropDown Component has been changed through user interaction or via the selectItem API method.
My suggestion would be to log this behavior in our GitHub repository here. This will give you the opportunity do directly communicate with our development team regarding the issue and get notifications whenever a new information is available.
Additionally another possible approach could be to use a conditional flag within the different lifecycle hooks in order to determinate whether the event has been emitted because of the preselection. Please keep in mind that initially the oldSelection filed of the onSelection event args is null. You can refer to the following sample I have prepared for you.
Please let me know if you need any further information!
Ok, so I've rooted out another issue related to dropdowns. The (onSelection) is firing when it's being created because it is being pre-populated with a value. Is there a way to prevent the onSelection action during render?
I have a grid that waits for user input to populate, but one of the dropdowns fires on render and on occasion, the grid populates without interaction, and without any useful data. I'm hoping to prevent this for improved user experience.
I’m glad that you find the provided information helpful.
Best Regards,Martin EvtimovAssociate Software DeveloperInfragistics, Inc.