Ion-select in v4 beta

Simple scenario
Parent component has an array, which is passed to child component with @Input().
child component displays a ion-select wit array elements as options.
parent modifies the array, but select popup(alert) remains same
I would expect options should reflect values of new array.
parent.ts


remainingBoards: number[];
  boardNo: number = 0;
  constructor() {
    this.remainingBoards = new Array(10 - this.boardNo).fill(0).map((x, i) => i + 1 + this.boardNo);
    this.boardNo = this.remainingBoards[0];
  }
  deleteFirst() {
    this.remainingBoards = new Array(10 - this.boardNo).fill(0).map((x, i) => i + 1 + this.boardNo);
    this.boardNo = this.remainingBoards[0];
  }

parent.html

<ion-content padding>
  <ion-button (click)="deleteFirst()"> delete first</ion-button>
  <app-select [remainingBoards]="remainingBoards" [boardNo]="boardNo"></app-select>
</ion-content>

child.ts

  @Input() remainingBoards: number[];
  @Input() boardNo: number;

child.html

<ion-item>
  <ion-label>
    <strong style="color:black">Board {{remainingBoards}}</strong>
  </ion-label>
  <ion-select value="{{boardNo}}">
    <ion-select-option *ngFor="let board of remainingBoards" value="{{board}}">{{board}}</ion-select-option>
  </ion-select>
</ion-item>

package.json

 "@angular/common": "6.0.9",
    "@angular/core": "6.0.9",
    "@angular/forms": "6.0.9",
    "@angular/http": "6.0.9",
    "@angular/platform-browser": "6.0.9",
    "@angular/platform-browser-dynamic": "6.0.9",
    "@angular/router": "6.0.9",
    "@ionic-native/core": "5.0.0-beta.14",
    "@ionic-native/splash-screen": "5.0.0-beta.14",
    "@ionic-native/status-bar": "5.0.0-beta.14",
    "@ionic/angular": "4.0.0-beta.0",
    "@ionic/ng-toolkit": "1.0.0",
    "@ionic/schematics-angular": "1.0.1",
    "core-js": "^2.5.3",
    "rxjs": "6.2.2",
    "zone.js": "^0.8.26"

Your component is not refreshing. If you did the equivalent of F5 on your component, you’d see the new array. If you want your Input() to update whenever new data is available, you need to use inside your input set/get and a Subject-type-thing. (I use BehaviorSubject.) Then your Input keeps listening, and presents new data to the component.

That would be disturbing if true. Change detection is supposed to handle this seamlessly.

Inside an ion-select? That isn’t in the Angular zone.

If you see the screenshot, the text elements (select header as well as popup header) has the new value of remainingboards. So component has the new value but select popup has a problem.

Selected value of the ion-select is also updated (by @input() boardNo).

Yeah, but you’re only rendering the select once, at construction time. You have to render it each time there’s an update.

now, that seems to be a problem

  1. How to know which components to re-render on data changes and which will update automatically?
  2. How to re-render select options alert?

Absolutely. This works as one would expect in Ionic 3:

@Component({templateUrl: "baby.html", selector: "baby"})
export class Baby {
  @Input() fruits: string[];
  fruit: string;
}

<ion-select [(ngModel)]="fruit">
  <ion-option *ngFor="let fruit of fruits" [value]="fruit">{{fruit}}</ion-option>
</ion-select>

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  fruits1 = ['apple', 'banana', 'cherry'];
  fruits2 = ['date', 'elderberry', 'fig'];
  fruits = this.fruits1;
  flipFruits(): void {
    this.fruits = this.fruits === this.fruits1 ? this.fruits2 : this.fruits1;
  }
}

<ion-content padding>
  <div><baby [fruits]="fruits"></baby></div>
  <div><button ion-button (click)="flipFruits()">flip fruits</button></div>
</ion-content>

as it happens, same code was working fine for me too in v3. have started porting to v4 and found this problem. I’m strongly of the opinion that its a bug, but wanted to give it a go here.

FWIW, I totally agree with you.

This is the code. It sounds as though you’re arguing for the reflectToAttr attribute on the options Prop to be set to true.

I can’t tell from a quick glance at the Stencil documentation whether reflectToAttr would achieve this or not, so I’ll take your word for it. In any event, all other ordinary Angular components propagate change detection automatically in situations like this, and I’m with @jhavinay that this one should as well.

  1. I can’t see reflectToAttr on header or subheader, but they display the new value.
  2. at a quick glance it seems the magic is being done by {} rater than reflect to attr, and options are already in curly braces.
    Having said that, let me clarify, i have never worked (or even looked at) stencil code before. So i might be miles off.
1 Like

Hi, man!
I have the same problem in Ionic v.4 stable release…
did you found a solution?
Thank you!

Having the same problem with the v4 RC. Is there any chance @AaronSterling ort someone else could give an example of how it should be done?

Having exactly the same issue. The attribute updates when the page is reconstructed, but not when doing change detection (not even on manual change detection trigger).

I can confirm that this has worked fine in ionic v3 as well, so in my mind definitely a bug in v4.

1 Like

I’m also seeing the exact same problem in ion-radio and ion-radio-group having switched to those to try and move my project along.

If someone could explain how the binding in V4 is supposed to work with a “Subject-type-thing” that would be really awesome.

Same problem here. Somebody find a solution?

Finally works for me using strings instead of integers in the ngModel and ion-select-options values.