[Ionic 4] ion-select and change detection

We are experiencing some problems in a page where we have 3 ion-select. The first one has two constant options while the second and the third load their options dynamically from an async service based on the previous select’s selection.

<ion-select formControlName="select1" name="select1" interface="action-sheet" placeholder="Choose one">
    <ion-select-option value="value1">Label1</ion-select-option>
    <ion-select-option value="value2">Label2</ion-select-option>
</ion-select>

<ion-select formControlName="select2" name="select2" interface="action-sheet" placeholder="Choose one">
    <ion-select-option *ngFor="let option of select2List" [value]="option">{{option.label}}</ion-select-option>
</ion-select>

<ion-select formControlName="select3" name="select3" interface="action-sheet" placeholder="Choose one">
    <ion-select-option *ngFor="let option of select3List" [value]="option">{{option.label}}</ion-select-option>
</ion-select>

We are using reactive forms to manage this form. Every time select1 changes, loads a new list of options for the second select and selects the first option. And every time select2 is changed, loads a new list of options for the third select and selects the first option.

// When select1 changes
this.myForm.get('select1').valueChanges.subscribe(selectedOption => {
    // We set the value of the second select to null for Change Detection to detect the change
    // Not sure if this is needeed
    this.myForm.get('select2').setValue(null);
    // We load the options for the second select
    this.dataService.getOptions1(selectedOption).subscribe(options => {
        this.select2List = options;
        // We set the first value by default
        this.myForm.get('select2').setValue(options[0]);
    });
});

// When select2 changes
this.myForm.get('select2').valueChanges.subscribe(selectedOption => {
	// We set the value of the third select to null for Change Detection to detect the change
    // Not sure if this is needeed
    this.myForm.get('select3').setValue(null);
    this.dataService.getOptions2(selectedOption).subscribe(options => {
        this.select3List = options;
        // We set the first value by default
        this.myForm.get('select3').setValue(options[0]);
    });
});

The problem we have noticed is that sometimes(randomly), when a value is set to one of the dynamic ion-selects using the “setValue” method of reactive forms, the change is not reflected in the UI.

It looks like the select has internally taken the new value, but the component doesn’t show it. The select itself appears with no selection (the placeholder is shown), but when you open the select the action-sheet shows the first element as selected.

I’m not sure if this has more to do with angular Change Detection or if is a component’s missbehaviour.

We have tried with a setTimeout in each “setValue” call, but the result is almost the same.

For whats it’s worth we are also seeing random issues with ion-select (ionic 4) where the data for the list updates via an async call. One thing to try is to force your final setValue to run inside the angular zone (inject zone and run inside zone.run(()={ .... })

I am experiencing this with Angular 7 and ionic 4. I tried using the fix that Webprofusion lists above but it did not work for me. I added a valueChanges event handler to the field and the value is indeed changing, but the value is not reflected in the field. Any suggestions for workarounds that others have been successful with?

I haven’t tried this with Ionic 4 yet, but see here for an approach that worked in the past.

Hey,

any luck / update with this?

I tried this but no luck! did anyone solve this ?

I solved this issue by adding 100ms delay after the async loading of data like this

setTimeout(() => {
        //your selected Item Model assignment
        this.modelABC = abc.id
      }, 100);

found solution here https://github.com/ionic-team/ionic/issues/17225#issuecomment-457452297

1 Like

This is the only workaround that we managed to get to work.
The issue is confirmed and apparently solved,

I had problem with the change detection for the options list.
That solved with hiding and showing the ion select with ngif.
But when the ngmodel is changed please double check if the set variable is integer.
because if you try to set string like “4” thats not going to work.

Hi there,
i too ran into this issue and was struggeling for two days.
Sadly the fix for mentioned issue #17225 is not solving the problem for Ionic 4 (@ionic/core 4.11.5)!

I commented on another issue https://github.com/ionic-team/ionic/issues/19324#issuecomment-564592797

this bug is really annoying :frowning:

1 Like

Hi, have the same problem on @ionic/angular 4.11.6

I faced the same issue in Ionic 4, my use-case is, I need to remove an option bases on a condition
. For that i have deleted the entire ion-select and created the new one. That helped me

use interface=“popover”

This didn’t helped me.

I tried everything frome setTimeout to zone.run to changeDetectorRef. In the end I found out the object values are not matched because two object were not referring to same memory location. I tried compareWith property of select component.

@ViewChild(IonSelect, {static: true}) select: IonSelect;
this.select.compareWith = () => {
  return // logic that returns boolean that decides a selected value
} 

Hope it helps.

Just so you know for me setTimeout worked!

setTimeout(() => {
  this.form.get(FormControlName).setValue(value);
}, 100)

My Ionic Info:

Ionic CLI                     : 6.2.2 (/usr/local/lib/node_modules/@ionic/cli)
Ionic Framework               : @ionic/angular 5.0.5
@angular-devkit/build-angular : 0.803.25
@angular-devkit/schematics    : 8.3.25
@angular/cli                  : 8.3.25
@ionic/angular-toolkit        : 2.2.0

What helped in our case was setting the model ([(ngModel)]="xxx") value to an empty string and then - with a timeout of 100 ms - setting it back to the real value. This causes the value to refresh (after a short flicker).