Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ion-select doesn't render selected value when filtered data used

I encountered strange bug with ion-select dynamic data filtering. In my application user should choose three security question during registration, so this questions cannot be the same. I have array of questions:

 questions: Array<{isSelected: boolean;question: string}> = [
    {isSelected: false, question: 'What is your pet’s name?'},
    {isSelected: false, question: 'What is the first name of the person you first kissed?'},
    {isSelected: false, question: 'Who was your childhood hero?'},
    {isSelected: false, question: 'What was your first grade friend last name?'},
    {isSelected: false, question: 'Where did you celebrate your 20th birthday?'},
    {isSelected: false, question: 'In what city or town does your nearest sibling live?'},
    {isSelected: false, question: 'What time of the day were you born?'}];

This part of my registration form looks like this:

    <ion-item>
      <ion-label floating>Select security question*</ion-label>
      <ion-select [(ngModel)]="regModel.SecurityQuestions[i].Question" name="Question"
                  [selectOptions]="sqSelectOptions"
                  (ionChange)="chooseQuestion(regModel.SecurityQuestions[i].Question)">
        <ion-option *ngFor="let sqOption of questions|filterSQ" value="{{sqOption.question}}"> {{sqOption.question}}
        </ion-option>
      </ion-select>
    </ion-item>

    <ion-item>
      <ion-label floating>Your answer*</ion-label>
      <ion-input type="text" required [(ngModel)]="regModel.SecurityQuestions[i].Answer" name="Answer"></ion-input>
    </ion-item>

  </div>

I use (ionChange)="chooseQuestion(regModel.SecurityQuestions[i].Question) to track selected options:

 chooseQuestion(s: string) {
    console.log(this.TAG + 'chooseQuestion: event value: ' + s);
    this.questions.filter(res => res.question == s).map(res => res.isSelected = true);
    //todo rewrite this 
    this.questions.filter(res => res.isSelected == true &&
    res.question != this.regModel.SecurityQuestions[0].Question &&
    res.question != this.regModel.SecurityQuestions[1].Question &&
    res.question != this.regModel.SecurityQuestions[2].Question)
      .map(res => res.isSelected = false);
    this.questions_filtered = this.questions.filter(res => res.isSelected == false);

    console.log(this.TAG + 'chooseQuestion: questions: ' + JSON.stringify(this.questions));
    console.log(this.TAG + 'chooseQuestion: questions_filtered: ' + JSON.stringify(this.questions_filtered));
  }

According to logs logic works fine. For the first time i used questions_filtered to provide questions for ion-select, and encountered problem: selected option doesn't display in UI field. Then I tried to use pipes as recommended way to filter data, same effect. I will appreciate any advice. Thank you.

UPDATE

To clarify the case I added some record and rewrote code a little bit. Two of three questions in this example have pipes and last one doesn't. I get correct values but without actual displaying.

enter image description here

Update

I still don't know why solution proposed by @misha130 didn't give any result. So I tried to dig around with Chrome inspector, and found out that this part wasn't called.(I copied highlighted part but I'm not sure was it correct) http://plnkr.co/edit/n4wv2UUdLtCmt4enYuVS?p=catalogue

like image 936
Autumn_Cat Avatar asked Mar 13 '26 19:03

Autumn_Cat


1 Answers

Angular2 doesn't detect changes in arrays and its children objects. For this to actual take effect in your view you'll have to call a change detection

import { ChangeDetectorRef } from '@angular/core';

// Inject to constructor
constructor(public cd:ChangeDetectorRef){}

// as per your example call it on in your ionChange method
chooseQuestion(s: string) {
  this.cd.detectChanges();
}

For more information: http://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

like image 180
misha130 Avatar answered Mar 15 '26 07:03

misha130