0

I have created a dropdown which has suppliers bound to it as an object.

<select class="form-control" name="supplier" required
                            [(ngModel)]="selectedSupplier" #supplier="ngModel">
    <option *ngFor="let supplier of suppliers" [ngValue]="supplier">{{supplier.name}}</option>
</select>

I have a grid on top of this dropdown where i select the values and add it in the table grid.

<tr *ngFor="let relationship of relationships">
     <td>{{relationship.supplierName}}</td>
     <td>{{relationship.businessArea}}</td>
     <td>{{relationship.contacts[0].name}}</td>
     <td><a href="javascript:void(0)" (click)="onEdit(relationship)">Edit</a></td>
</tr>

relationship has supplierName as well as supplierId. I am trying to select the value of the dropdown onEdit event but i can't seem to make it work. below are my attempts so far.

First Attempt:

private selectedSupplier: any;
private onEdit(relationship: Relationship): void {
        this.selectedSupplier = {id: relationship.supplierId, name: relationship.supplierName};
    }

Second Attempt:

private selectedSupplier: Dictionary;
private onEdit(relationship: Relationship): void {
        this.selectedSupplier = new Dictionary(relationship.supplierId, relationship.supplierName);
    }
export class Dictionary{
       constructor(public id:number, public name:string){}
}

Third Attempt:

private selectedSupplier: any;
private onEdit(relationship: Relationship): void {
        this.selectedSupplier.id = relationship.supplierId;
     // this.selectedSupplier.id = 2;
    }

any idea how can i acheive that? below is the screenshot...

enter image description here

I have created a simple plunker as well... https://plnkr.co/edit/Z11peGQmzYuwY6l6U9Ri?p=preview

Kamran Pervaiz
  • 1,861
  • 4
  • 22
  • 42

2 Answers2

4

It seems Angular2 uses objects reference, instead of properties, so if you do this, it will work:

private onEdit(relationship: Relationship): void {
  this.selectedSupplier = this.suppliers.find(supplier => supplier.id === relationship.supplierId);
}

You need to pass the exact same object from the select.

Fabio Antunes
  • 22,251
  • 15
  • 81
  • 96
  • thanks will try this solution but my suppliers are coming from http get from an api. I guess it wont change it but will try and let you know. thanks – Kamran Pervaiz Aug 23 '16 at 19:38
  • Just use the same array of suppliers you use to populate your select input – Fabio Antunes Aug 23 '16 at 22:40
  • 1
    thanks for this suggestion. its very elegant and working "You need to pass the exact same object from the select" this helped alot. :) – Kamran Pervaiz Aug 24 '16 at 12:55
  • any idea how to get the selected value on change? $event.target.value is just giving me "0: Object" I am not sure how to get the actual Id/value – Kamran Pervaiz Aug 24 '16 at 15:45
  • can you please have a look on below question? http://stackoverflow.com/questions/39141860/angular-2-wait-for-synchronous-method – Kamran Pervaiz Aug 25 '16 at 09:46
1

The problem is that you are setting the option value to be an Object, so when you set the selected relationship value you need to set the same exact object (not a similar representation of it) for the ngModel to know exactly which Option to set as selected. For example this fork of your plunker: https://plnkr.co/edit/VroxlTMkV30HbqB1DvYq.

onEdit(relationship){
    let name:string = relationship.supplierName;
    let found:boolean = false;
    for (let i = 0; i < this.suppliers.length && !found; i++) {
      let supplier:any = this.suppliers[i];
      if (supplier.name === name) {
        found = true;
        this.selectedSupplier = supplier
      }
    }
    /* if (!found) what to do? */
  }
}

That uses the relationship's name, searches through the list of the suppliers, then sets the selectedSupplier to the one with the correct name.

I don't really like setting the value of Options to an Object, though. If I were to design it, I would prefer to use the IDs as the Option value, it would make the code a lot easier.

Steven Luke
  • 524
  • 2
  • 7