34

I'm using Ionic v2 and I can not set the selected value when showing the page.

<ion-select [(ngModel)]="company.form">
    <ion-option *ngFor="let form of forms" [value]="form" [selected]="true">{{form.name}}</ion-option>
</ion-select>

I've tried with checked, too but that isn't work either. How can I do this?

Cordova CLI: 6.4.0
Ionic Framework Version: 2.0.0-rc.3
Ionic CLI Version: 2.1.13
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.45
Mistalis
  • 17,793
  • 13
  • 73
  • 97
Perrier
  • 2,753
  • 5
  • 33
  • 53

9 Answers9

20

If you deal with default value xor objects, the cleanest way is to provide a compare function to the [compareWith] attribute. This function takes 2 objects in parameters and returns true if they are equals. This way, existing values in model will be selected at start. This works too if new data are added in model outside of the select.

Following example is taken from official Ionic doc

<ion-item>
  <ion-label>Employee</ion-label>
  <ion-select [(ngModel)]="employee" [compareWith]="compareFn">
    <ion-option *ngFor="let employee of employees" [value]="employee"></ion-option>
  </ion-select>
</ion-item>

compareFn(e1: Employee, e2: Employee): boolean {
  return e1 && e2 ? e1.id == e2.id : e1 == e2;
}

EDIT : using double equals make it work for Ionic 4 (as Stan Kurdziel suggests in comment)

Nicolas Janel
  • 3,025
  • 1
  • 28
  • 31
  • I think this should be the accepted answer. It's cleaner, more straight forward and the official ionic suggestion - https://ionicframework.com/docs/api/components/select/Select/#object-value-references – Vlad Topala Oct 06 '18 at 02:29
  • Thanks! the binding worked fine for me without [compareWith] in Ionic 3 (not even using objects, just numbers for the values), but quit working in Ionic 4... Adding compareWith AND using only double equals instead of triple equals fixed Ionic 4 for me. – Stan Kurdziel May 17 '19 at 00:30
  • 1
    This doesn't work in newer version of ionic. Any change in the selected value isn't reflected. – invot Oct 30 '19 at 18:20
  • 2
    @invot replace triple equals with double as it seems Ionic 4 mix string & int values – Nicolas Janel Nov 01 '19 at 23:28
16

The problem seems to be that ion-option don't like objects in rc3. I have to work with only the id part of the object and write a seperate changehandler that find the needed object and set it as a value.

  <ion-select [ngModel]="company.form.id" (ngModelChange)="companyFormSelected($event)" okText="Ok" cancelText="Mégsem">
    <ion-option *ngFor="let form of forms" [value]="form.id" [selected]="form.id == company.form.id">{{form.name}}</ion-option>
  </ion-select>

And the changehandler:

companyFormSelected(newform) {
    let selectedForm = this.forms.find((f)=>{
      return f.id === newform;
    });
    this.company.form=selectedForm;
}

This seems to be a bug in rc3 but I don't know where can I report bugs. I did open a topic on ionic forum.

Perrier
  • 2,753
  • 5
  • 33
  • 53
12
<ion-select [(ngModel)]="name">// binding the value available from ts file
    <ion-option *ngFor="let form of forms; let idx = index" [value]="form.name"  selected="{{(idx==0).toString()}}">{{form.name}}</ion-option>
</ion-select>

inside your ts file

name = this.forms[0].name //assign the variable name to the first index of your array
Mohan Gopi
  • 7,606
  • 17
  • 66
  • 117
  • 1
    Will this work? It seems you are now binding `ngModel` on the select to a string, but the option values are all objects. – Lex Dec 14 '16 at 15:46
  • Okay, at least it showed that this ion-option thing in rc3 actually can show a default value. However the solution is not to use objects in it and index doesn't have to be involved either. Thanks for your time @MohanGopi – Perrier Dec 15 '16 at 09:25
8

This is working for me.

In html :

<ion-select [(ngModel)]="company.form">
    <ion-option value="frm1"> Form 1 </ion-option>
    <ion-option value="frm2"> Form 2 </ion-option>
</ion-select>

In ts :

company = {
   form:null
}; 

constructor(){
   this.company.form = "frm1";
}
Khurshid Ansari
  • 4,638
  • 2
  • 33
  • 52
7
<ion-select ([ngModel])="dropdown1">
  <ion-select-option value="1">Item1</ion-select-option>
  <ion-select-option value="2">Item2</ion-select-option>
</ion-select>

the following will not work:

dropdown1 = 2;

but the following will work:

dropdown1 = 2 + "";

The select option values are treated as string, so you should assign string values to your model variable so that comparison will not fail.

Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88
4

You do not need to work with the attribute selected or [selected] it is not necessary

<ion-select [(ngModel)]="company.form.id" name="company.form.id">
    <ion-option *ngFor="let form of forms" value="{{ form.id }}">
      {{ form.name }}
    </ion-option>
</ion-select>
0077cc
  • 61
  • 1
  • 1
  • As far as I know this was a bug in ionic v2 rc-3 and was fixed in the final release. I suppose your solution is working now, looks the way it should work and my solution was a workaround for the bug in rc-3. So for future reference I set your answer as the best solution for my original question. Thanks for your answer! – Perrier Dec 07 '17 at 07:38
  • if I initialize company.form.id=2, it shouldn't visually appear that option selected? It's not happening and don't know why... – Ari Waisberg Dec 24 '18 at 19:16
2

To make long story short, and quoting ionic documentation (always reference the original source ): "A select should be used with child elements. If the child is not given a value attribute then its text will be used as the value. If value is set on the , the selected option will be chosen based on that value."

...hence....make sure value attributes on your ionic-select and ionic-select-option reference the same javascript object.attribute in your code...basically point to the same thing..see below page level attribute value="{{ country.id }}" in both ionic-select and array level value="{{c.id}}" ionic-select-option

Please notice that ngModel is no longer managing the page level country attribute lifecycle

    <ion-item>
        <ion-select *ngIf="countries.length > 0"
                     (ionChange)="onCountryChaged($event)"
                     interface="popover"
                      clearInput="true"
                      placeholder='Country (required)'
                       value="{{ country.id }}">
            <ion-select-option lines="none"
              *ngFor="let c of countries"
               value="{{ c.id }}"> {{ c.label }}
            </ion-select-option>
        </ion-select>
     </ion-item>
        
        
Inside the .ts file we can now set *country* member programmatically
Page:constructor();
    this.platform.ready().then(async () => {
        this.getCountries(); //load list of countries from provider
        this.country = this.navDataService.getCountry();//local data store to save state between pages
        }).catch(error => { });
        
Page:EventHandler onCountryChaged(event): void {
     
    let id = event.detail.value;
    this.country = this.countries.find( item => item.id == id ) ;
    this.navDataService.setCountry(this.country);
}
            
     
Taras Gleb
  • 158
  • 2
  • 5
  • Kinda wish I could upvote this answer more than once for the insight it provides. The tip about making sure that the values in ion-select and ion-select-option match just saved my current branch. – JurgenBlitz Oct 07 '21 at 08:31
1

Inside ion-option, you can do

<ion-option [attr.selected]="(form.name == name) ? true : null"> {{ form.name }} </ion-option>
  • 2
    Didn't work. Tried with [attr.checked], too but that didn't do it either. Do you use the same ionic version and this works for you? – Perrier Dec 15 '16 at 08:51
1
  in html---->

     <ion-item text-center >
        <ion-select  [(ngModel)]="selectedQuestion" placeholder="Choose Security Question" >
          <ion-option *ngFor="let q of questionArray let i=index"  selected="{{(i==defaultSelectQuestion).toString()}}"  >
             {{q}}
            </ion-option>
        </ion-select>
      </ion-item>


in ts---->
//if u dont want any default selection
    this.defaultSelectQuestion = -1; 

//if first element should be your default selection
  this.defaultSelectQuestion = 0;



this.selectedQuestion=this.questionArray[this.defaultSelectQuestion]
Fir
  • 73
  • 3