Ionic-framework: Ion-option not preselected when value is translation

Created on 7 Oct 2016  路  17Comments  路  Source: ionic-team/ionic-framework

Short description of the problem:

When using translations as text values in ion-option (ion-select) then value in value is ignored and I guess it is comparing text in the option and not actual value attribute, I tried also wrapping value in [value] but it didn't help. From testing, option _is_ selected, just UI don't get updated to match that selection.

What behavior are you expecting?

To ion-option get preselected in model and in UI.

<ion-item>
          <ion-label>{{card.exp_month}} / {{ 'PAYMENT.expire' | translate }}</ion-label>
          <ion-select [(ngModel)]="card.exp_month" placeholder="{{ 'FORM.month' | translate }}" cancelText="{{ 'BUTTONS.cancel' | translate }}" required formControlName="exp_month" ngDefaultControl>
            <ion-option value="1">{{ 'MONTHS.january' | translate }}</ion-option> <!-- This doesn't work when card.exp_month=1 -->
            <ion-option value="2">2</ion-option> <!-- This does work when card.exp_month=2 -->
            <ion-option value="3">{{ 'MONTHS.march' | translate }}</ion-option>
            <ion-option value="4">{{ 'MONTHS.april' | translate }}</ion-option>
            <ion-option value="5">{{ 'MONTHS.may' | translate }}</ion-option>
            <ion-option value="6">{{ 'MONTHS.june' | translate }}</ion-option>
            <ion-option value="7">{{ 'MONTHS.july' | translate }}</ion-option>
            <ion-option value="8">{{ 'MONTHS.august' | translate }}</ion-option>
            <ion-option value="9">{{ 'MONTHS.september' | translate }}</ion-option>
            <ion-option value="10">{{ 'MONTHS.october' | translate }}</ion-option>
            <ion-option value="11">{{ 'MONTHS.november' | translate }}</ion-option>
            <ion-option value="12">{{ 'MONTHS.december' | translate }}</ion-option>
          </ion-select>
<!-- This code work perfect if card.exp_year=2020 for example-->
          <ion-select [(ngModel)]="card.exp_year" placeholder="{{ 'FORM.year' | translate }}" cancelText="{{ 'BUTTONS.cancel' | translate }}" required formControlName="exp_year" ngDefaultControl>
            <ion-option value="2016">2016</ion-option>
            <ion-option value="2017">2017</ion-option>
            <ion-option value="2018">2018</ion-option>
            <ion-option value="2019">2019</ion-option>
            <ion-option value="2020">2020</ion-option>
            <ion-option value="2021">2021</ion-option>
            <ion-option value="2022">2022</ion-option>
          </ion-select>
        </ion-item>

Which Ionic Version? 1.x or 2.x
Ionic 2 RC0

Run ionic info from terminal/cmd prompt: (paste output below)

Your system information:

Cordova CLI: 6.3.1
Gulp version: CLI version 3.9.1
Gulp local: Local version 3.9.1
Ionic Framework Version: 2.0.0-rc.0
Ionic CLI Version: 2.1.0
Ionic App Lib Version: 2.1.0-beta.1
ios-deploy version: 1.8.6
ios-sim version: 5.0.8
OS: Mac OS X El Capitan
Node Version: v5.11.1
Xcode version: Xcode 7.3.1 Build version 7D1014

v3

Most helpful comment

Issue still occurring in latest version of Ionic:

cli packages: (D:\Projects\progressa\demo\node_modules)
    @ionic/cli-plugin-cordova       : 1.6.1
    @ionic/cli-plugin-ionic-angular : 1.4.1
    @ionic/cli-utils                : 1.7.0
    ionic (Ionic CLI)               : 3.7.0

global packages:
    Cordova CLI : 7.0.1

local packages:
    @ionic/app-scripts : 2.1.3
    Cordova Platforms  : android 6.2.3
    Ionic Framework    : ionic-angular 3.6.0

System:
    Node : v8.2.1
    OS   : Windows 10
    npm  : 5.3.0

All 17 comments

Hello, thanks for opening an issue with us! Note to team: This issue is reproducible with the above test code.

What's the status of this? Is there a fix in progress?

I'm running into this as well. Doesn't matter if you use the translation pipe - any variable outputted in the ion-option will cause it to show as blank. Still present in RC4. My plunker here:
http://plnkr.co/edit/u1nnR1RILV4jeJCK2ShH?p=preview

1)
want to confirm the issue behavior is as what @beloitdavisja said, not limited to translation:
text of selected ion-option is not displayed, if the ion-option text is the output of angular view interpolation i.e. {{ variable }}

2)
after reading the current code base, there is no way to push or tell ion-select to re-render after the interpolation has been done.

3)
Another workaround I used, using [placeholder] to workaround it.
The drawback is that this ion-select will lose the original placeholder style.

First, display the selected option text as placeholder:

<ion-select
  formControlName="gender"
  [(ngModel)]="user.gender"
  [placeholder]="{{ selectedOptionAsPlaceholder }}"
>

Then, set the selectedOptionAsPlaceholder value in the component (.ts).
You may want to show the placeholder text when the ngModel variable is not set yet.

Finally, override the default placeholder style as black

page-xxx {
    ion-select[formcontrolname="gender"] {
      .select-icon-inner,
      .select-placeholder {
        color: black;
      }
    }
}

Same problem here with ng2-translate :(

Still getting this issue in 2.2.0, without translate

Still getting this issue in 2.3.0, with translate 馃憥
Works with the solution of @3dd13 , thanks

This issue still exists, with translate. System information as per below:

Cordova CLI: 6.5.0
Ionic Framework Version: 3.0.1
Ionic CLI Version: 2.2.2
Ionic App Lib Version: 2.2.1
Ionic App Scripts Version: 1.3.1

Still not working:

@ionic/cli-utils : 1.1.2
Cordova CLI      : 7.0.1 
Ionic CLI        : 3.1.2
@ionic/app-scripts              : 1.3.7
@ionic/cli-plugin-cordova       : 1.1.2
@ionic/cli-plugin-ionic-angular : 1.1.2
Ionic Framework                 : ionic-angular 3.1.1

Ugly, but working solution:

private units : string[];

constructor() {
  this.units=this.unitsForSelect;
}

// load translations into array:
get unitsForSelect(){
  let units = [];
  units.push({ code : 'imperial', name : this.translate.instant('universal.units_imperial') });
  units.push({ code : 'metric', name : this.translate.instant('universal.units_metric') });
  return units;
}

// modify language change to:
onLangChange() {
  this.translate.use(this.selectedLang).subscribe(() => {
    this.units=this.unitsForSelect;
  });
}

Select template

<ion-select name="units" [(ngModel)]="selectedUnits">
  <ion-option *ngFor="let unit of units" [value]="unit.code">{{ unit.name }}</ion-option>
</ion-select>

Issue still occurring in latest version of Ionic:

cli packages: (D:\Projects\progressa\demo\node_modules)
    @ionic/cli-plugin-cordova       : 1.6.1
    @ionic/cli-plugin-ionic-angular : 1.4.1
    @ionic/cli-utils                : 1.7.0
    ionic (Ionic CLI)               : 3.7.0

global packages:
    Cordova CLI : 7.0.1

local packages:
    @ionic/app-scripts : 2.1.3
    Cordova Platforms  : android 6.2.3
    Ionic Framework    : ionic-angular 3.6.0

System:
    Node : v8.2.1
    OS   : Windows 10
    npm  : 5.3.0

For everyone that still struggling with this, found a solution that worked for me.

By forcing update on all Select components using QueryList you should be able to get the translated string to show.

@ViewChildren(Select) ionSelects: QueryList<Select>;

Then:

ionViewDidLoad() {
    this.ionSelects.map((select) => select._inputUpdated());
  }

Found this on https://github.com/ionic-team/ionic/issues/12179

I had the exact same issue, fixed with the translate attribute.

<ion-select [(ngModel)]="card.exp_month" placeholder="{{ 'FORM.month' | translate }}" cancelText="{{ 'BUTTONS.cancel' | translate }}" required formControlName="exp_month" ngDefaultControl>
    <ion-option value="1" translate="MONTHS.january"></ion-option>
    <ion-option value="2" translate="MONTHS.february"></ion-option>
    <!-- And so it goes... -->
</ion-select>

Don't really know why though, @presende solution worked for me so my guess is that translate pipe is messing up the initialization on the ion-select.

Not sure where the issue may come from.
After reading the source code of both the Select and Option components, and also the Angular's QueryList and the ContentChildren decorator documentations, I think the issue may be that the Select component options QueryList isn't being updated (even when I subscribed while debugging the Select code), maybe because the Option elements where never added to the DOM with __ (or similar) but just kept from the ContentChilder setter here https://github.com/ionic-team/ionic/blob/v3/src/components/select/select.ts#L451

Just guessing. Ionic team could also have set a setter for the Option's text property and then just let the parent about any text change (just guessing, no idea if it would work) https://github.com/ionic-team/ionic/blob/v3/src/components/option/option.ts#L67

Anyways, I managed to do a quick workaround to update the Select text after a some thinkering by using the [selectedText], and inspired (after some Googling this issue) on KKHAN's post on https://forum.ionicframework.com/t/issue-with-ion-select-and-ion-option/105243

<ion-label>{{ 'select-2-label' | translate }}</ion-label>
<ion-select interface="popover" [(ngModel)]="select2Value"
            [selectedText]="(select2Value === '') ?
            ('selects-option-txt-all' | translate) : undefined">
    <ion-option value="" >{{ 'selects-option-txt-all' | translate }}</ion-option>
    <ion-option value="text_2">Text 2</ion-option>
</ion-select>

It just uses the template to drive the workaround.
Hopefully this helps anyone arriving here (and this gets fixed by either Angular or Ionic team sometime in the near future).

This issue has been automatically identified as an Ionic 3 issue. We recently moved Ionic 3 to its own repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.

If I've made a mistake, and if this issue is still relevant to Ionic 4, please let the Ionic Framework team know!

Thank you for using Ionic!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BilelKrichen picture BilelKrichen  路  3Comments

SebastianGiro picture SebastianGiro  路  3Comments

Nick-The-Uncharted picture Nick-The-Uncharted  路  3Comments

giammaleoni picture giammaleoni  路  3Comments

daveshirman picture daveshirman  路  3Comments