Ionic 4 not showing selected value in ion-select

Problem:
I have an ion-select and in the controller when the user does something, I populate the ion-select with 1 value and make that value the selected value. The ion-select does not show that the value has been selected, but the [(ngModel)] is the correct value. When I open the ion-select it shows the value in the list and it is selected, when selecting the value in the list again it goes over the ion-select label.

Screenshots:

  1. The Make has value of CHEVROLET but it is not selected by ion-select

  2. When tapping on ion-select, it shows the CHEVROLET as selected and CHEVROLET goes over the Make label

HTML:

<ion-item>
   <ion-label position="floating">
      <span class="required">* </span>Make
   </ion-label>
   <ion-select [interfaceOptions]="global.compactAlertOptions" id="make" [(ngModel)]="global.valuation.vehicle.make" name="make" #makeRef="ngModel" required>
      <ion-select-option *ngFor="let make of makes">{{make}}</ion-select-option>
   </ion-select>
</ion-item>
<ion-label *ngIf="makeRef.touched && makeRef.invalid && makeRef.errors.required" class="error">Make is required</ion-label>

Controller:

  1. Modal Controller (the Make gets set in a popup modal):
      this.global.valuation.vehicle.make = this.vehicleDetails.VehicleMake;
  1. Populate the ion-select in parent controller:
      this.makes = [this.global.valuation.vehicle.make];

you can use placeholder instead of label.

Thanks for the reply, but will a placeholder have the floating effect as a label and I am also using a CSS class inside the label, not sure if it’s possible with a placeholder

Yea placeholder will not have that effect…

Hi,
I had the same problem, add a timeout and it will work

setTimeout(() => {
     // your code
    }, 100);

Please don’t take the advice in the post above this one.

setTimeout, especially with magic numbers, is something that should be avoided as much as humanly possible. It deliberately obscures either a race condition or a problem with change detection that should rather be addressed directly.

To OP: aside from the scoping concerns of what appears to be going on with global here (which I think are legitimate), I worry about change detection and deep object inspection here. Can you try an experiment and do whatever is necessary to eliminate all dots from the [(ngModel)] binding and see if your problem still persists?

1 Like

Thanks for the reply.

I did a test where instead of this.global.valuation.vehicle.make I use this.make and it worked fine.
So is there a restriction on how many child properties the model variable must have? Because the global variable I use on 3 pages (to pass data between these 3 components).

I added an on change event on the this.make where I stamp the global variable with this.make and this seems to work fine, but sort of a “hackey way” to make it work

I would phrase it more as “how many levels deep of inspection you can reasonably expect Angular’s change detection to notice stuff at”, and it’s possible that things have gotten better on this front since I repeatedly stepped on this rake, but my rule is “1”. I would not bind anything deeper than foo.bar.

I figured as much. Perhaps while we’re here I could impose on you to check out this post? When I was exposing stuff like this as a plain variable, I kept running into the problem of “how do I communicate changes to consumers (pages/components that care)?”. Exposing them as Observables in the service solves that problem, and incidentally should solve this one as well, because your subscription to global.valuation$ will take care of updating a property in the page controller.

…and that refactoring should obviate the need for this as well.

1 Like

Awesome thanks. Will definitely make use of this. Nice way to make variable available across components. Guess I learn something new every day :muscle: