Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<ion-select> cannot select correct option if its values are objects, and ngModel is tied to a different object. #6625

Closed
zakton5 opened this issue May 23, 2016 · 16 comments
Assignees

Comments

@zakton5
Copy link
Contributor

zakton5 commented May 23, 2016

Short description of the problem:

cannot select the appropriate option if its values are objects, but the value tied to ngModel is another object with the same properties.

What behavior are you expecting?

I expect the correct option to be selected when the page loads, despite the fact that they are different objects with the same properties.

Assuming I have the following options tied to my ion-select:

options: any[] = [
        {
          key: 1,
          value: "test 1"
        },
        {
          key: 2,
          value: "test 2"
        },
        {
          key: 3,
          value: "test 3"
        },
      ];

and I assign the selected option like this:

this.selectedOption = this.options[1];      

It will correctly display the option. However, if I assign it like this (creating a new object with the same properties)

 this.selectedOption2 = {
          key: 3,
          value: "test 3"
        };

Then the ion-select will be blank

Suggestions:
The option to select is determined by a function that checks for exact equality (or object equality). Perhaps there should be an option that the user can pass in to the ion-select, something like trackBy, that will examine the object values' properties instead of the objects themselves.

Which Ionic Version?
2.x beta 6

Codepen

http://codepen.io/anon/pen/LNweqo

Run ionic info from terminal/cmd prompt: (paste output below)
Cordova CLI: 6.0.0
Gulp version: CLI version 3.9.0
Gulp local: Local version 3.9.1
Ionic Framework Version: 2.0.0-beta.6
Ionic CLI Version: 2.0.0-beta.25
Ionic App Lib Version: 2.0.0-beta.15
ios-deploy version: 1.8.4
ios-sim version: 5.0.6
OS: Mac OS X El Capitan
Node Version: v4.4.4
Xcode version: Xcode 7.3 Build version 7D175

@zakton5
Copy link
Contributor Author

zakton5 commented May 23, 2016

I've implemented a solution, and it seems to work properly, and I plan to submit a PR.

I've added an @input() property that takes in a string value that represents the object property to compare. My only question is, what should I name it? As of now, it is called 'trackBy'. I could also call it 'property' or something like that. Any feedback?

@zakton5
Copy link
Contributor Author

zakton5 commented Aug 4, 2016

I've already commented the below on the PR for this issue. I'm putting it here just for an update and a work around solution.

@cleever, angular does support this but not for my specific use case. I am pulling my pre-selected objects from a database. Therefore, the list of objects in my component, and the actual object used for the model value is a completely different object, even though it has the exact same properties.

I ended up doing this, which is similar to @xr0master's solution.

<ion-select [ngModel]="someProperty.id" (ngModelChange)="selectObjectById(list, $event, 'someProperty')">
    <ion-option *ngFor="let item of list" [value]="item.id">{{item.name}}</ion-option>
</ion-select>
public selectObjectById(list: any[], id: string, property: string) {
    var item = list.find(item => item._id === id);
    var prop = eval('this.' + property);
    prop = property;
}

This is essentially what the pull request did in the first place. It's unfortunate that this is necessary, but it works as desired.

@jgw96 jgw96 removed the platform:ios label Aug 5, 2016
@jonathan-chin
Copy link

I am currently experiencing the same issue. ion-select does not behave as expected when value is an object.

any updates on this?

@rolandjitsu
Copy link

The proper option does not get selected neither if the value is null:

<ion-select [ngModel]="category" (ngModelChange)="selectCategory($event)" name="category">
    <ion-option [value]="null">
        None
    </ion-option>
    <ion-option *ngFor="let category of categories | async" [value]="category">
        {{category}}
    </ion-option>
</ion-select>

If category is null I'd expect that the first option with None is selected, but neither options is selected.

@dpanko2005
Copy link

This worked for me. The selected value is an object

<ion-item> <ion-label>*Select Units :&nbsp;</ion-label> <ion-select (ionChange)="unitSelectionChangeModal()" class="gsValidate gsSmallText" name="activeUnit" [(ngModel)]="activeUnit" required> <ion-option value=""></ion-option> <ion-option *ngFor="let item of activeSupportedUnits" [value]="item">{{item.abbrev}}</ion-option> </ion-select> </ion-item>

@zakton5
Copy link
Contributor Author

zakton5 commented Jun 3, 2017

Hey ionic team @jgw96 @manucorporat ! This could be fixed by using Angular 4's new compareWith directive. Select API and compareWith
Those docs also explain well the problem that I have been trying to express this whole time.

@zakton5
Copy link
Contributor Author

zakton5 commented Jun 7, 2017

I'm just going to make a PR for this and use the same logic as Angular's compareWith

@yanxiaodi
Copy link

I found the same problem. And if the data comes from a promise, it still has error about ngModel binding.

@granthoff1107
Copy link

Why is it always impossible to get a response from the Ionic Team?

@yanxiaodi
Copy link

@granthoff1107 You can try compareWith directive to solve this problem. It works well. But I still didn't find a way to correctly use ion-select with the data from a promise.

@pk359
Copy link

pk359 commented Oct 5, 2017

<ion-select #country [(ngModel)]="countryData" > <ion-option *ngFor="let country of countries" value="{{stringify(country)}}" {{country.name}}</ion-option> </ion-select>

please note stringfiy is a function that just stringifies whole object. It may pose performance issue.

@chrisjpalmer
Copy link

This works for me.

Following the documentation linked above:
screen shot 2017-10-10 at 11 28 21 am

I made the following in component html:
screen shot 2017-10-10 at 11 29 46 am

And made the following function for comparing the different objects:
screen shot 2017-10-10 at 11 31 12 am

My ionic info is:


    @ionic/cli-utils  : 1.12.0
    ionic (Ionic CLI) : 3.12.0

global packages:

    cordova (Cordova CLI) : 7.0.1

local packages:

    @ionic/app-scripts : 2.1.4
    Cordova Platforms  : android 6.2.3 browser 4.1.0 ios 4.5.0
    Ionic Framework    : ionic-angular 3.6.0

System:

    Android SDK Tools : 25.2.5
    ios-deploy        : 1.9.2
    ios-sim           : 6.0.0
    Node              : v6.9.4
    npm               : 3.10.10
    OS                : macOS Sierra
    Xcode             : Xcode 9.0 Build version 9A235

Misc:

    backend : pro```

@bkarv
Copy link

bkarv commented Oct 13, 2017

The above worked for me too. Thanks!

@MattWlodarski
Copy link

The above worked for me too even if I load in the options with an async pipe.

@NicksonYap
Copy link

The above worked for me too! Angular/Ionic should have this built in.
Probably a [trackBy]="country.id" if using this example #6625 (comment)

@ionitron-bot
Copy link

ionitron-bot bot commented Sep 1, 2018

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Sep 1, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests