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

Error when using object values in ng-option with reactive forms #414

Closed
wkiril opened this issue Apr 4, 2018 · 13 comments
Closed

Error when using object values in ng-option with reactive forms #414

wkiril opened this issue Apr 4, 2018 · 13 comments
Assignees

Comments

@wkiril
Copy link

wkiril commented Apr 4, 2018

Expected behaviour

It should be possible to use ng-option component with an object in [value] using the reactive forms

Actual behaviour

https://plnkr.co/edit/m0oMVG6uvfHKp5ai3uSL?p=preview

Here's the error
Cannot read property 'indexOf' of undefined
at ItemsList.resolveNested (ng-select.js:1207)
at ItemsList.mapItem (ng-select.js:1223)
at select (ng-select.js:2110)
at NgSelectComponent._handleWriteValue (ng-select.js:2125)
at NgSelectComponent.writeValue (ng-select.js:1874)
at setUpControl (forms.js:2300)
at FormGroupDirective.addControl (forms.js:6659)
at FormControlName._setUpControl (forms.js:7309)
at FormControlName.ngOnChanges (forms.js:7222)
at checkAndUpdateDirectiveInline (core.js:12396)

More Info

ng-select version: 0.35.0

browser: Chrome

reproducible in demo page: NO

@anjmao
Copy link
Member

anjmao commented Apr 5, 2018

Hi @wkiril
If you pass value as object you need to add bindLabel because internally ng-select should know how to resolve your [value]="city" label (required for search so on)

<ng-select 
          placeholder="Select city"
          bindLabel="name"
          formControlName="city">
          <ng-option
            *ngFor="let city of cities" 
            [value]="city">{{ city.name }}
         </ng-option>
</ng-select>

I see that it would be good to add validation for inputs so end user can better see that is required at which case.

@wkiril
Copy link
Author

wkiril commented Apr 5, 2018

can't the value inside the ng-option tags be used as label? my use case is a little bit different:

<ng-select formControlName="city">
    <ng-option 
        *ngFor="let city of cities" 
        [value]="city"
    >{{ city.name }}</ng-option>
    <ng-option 
        *ngIf="form.value.city === 'custom'" 
        [value]="'custom'"
    >Custom city</ng-option>
    <ng-template ng-footer-tmp>
        <a (click)="openCustomCityModal()">Custom city</a>
    </ng-template>
</ng-select>

so the values are different - an object and a simple string. it could be done with a normal select but I need the footer template

@wkiril
Copy link
Author

wkiril commented Apr 5, 2018

I also noticed that using bindLabel without [items] (as in your example) doesn't show the label

@anjmao
Copy link
Member

anjmao commented Apr 5, 2018

You are correct, option innerHTML can be used as label and bindLabel can be ignored. I looked at the code and it needs to be refactored a bit to support this case.

Implementation note:
https://github.com/ng-select/ng-select/blob/master/src/ng-select/ng-select.component.ts#L462 Do not try to resolve nested value label if label is already set.

@anjmao anjmao added bug and removed improvement labels Apr 5, 2018
@anjmao anjmao self-assigned this Apr 5, 2018
@anjmao
Copy link
Member

anjmao commented Apr 5, 2018

@wkiril I added example b93b25a It is not possible to use objects and primitive values, when using ng-option you should use primitive [value] when it is working fine.
In your example instead of passing whole city you can pass only city id.

@emmanueldaher
Copy link

I got the same problem, i'm also using ng-option passing an object as [value].
I'll pass object.id as [value] temporarily, as suggested by @anjmao.

@wkiril is version 0.35.0 available on npm?

@anjmao anjmao added improvement and removed bug labels Apr 5, 2018
@anjmao
Copy link
Member

anjmao commented Apr 5, 2018

@emmanueldaher Yes it is available.
@wkiril If you need to bind object you pass items to [items] input and use custom ng-option template.

@wkiril
Copy link
Author

wkiril commented Apr 5, 2018

yes, thanks @anjmao for the quick replies. I know the workarounds

@wkiril
Copy link
Author

wkiril commented Apr 10, 2018

there's still an inconsistency using a simple string ng-option and reactive forms: https://stackblitz.com/edit/ng-select-xsyqyl

the initial value is displayed instead of the label from the ng-option innerHTML

@wkiril
Copy link
Author

wkiril commented Apr 11, 2018

this is also observable in the default demo page https://ng-select.github.io/ng-select#/forms

@anjmao
Copy link
Member

anjmao commented Apr 16, 2018

@wkiril Thanks for good example on inconsistency 👍

@wkiril
Copy link
Author

wkiril commented Apr 17, 2018

thank you for the fix. however now the html doesn't render on the Basic select in Reactive forms demo page - https://ng-select.github.io/ng-select#/forms

jakemdunn pushed a commit to jakemdunn/ng-select that referenced this issue Oct 16, 2018
@kuncevic
Copy link

got an error TypeError: key is undefined adding bindLabel as per #414 (comment) solved the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants