Sunday, 1 September 2019

How do I pre-populate an Angular 7 menu used as an attribute of adding a component?

I'm using Angular 7. I define an order, src/app/order.ts, like this

import { Product } from './product';

export class Order{
    public id:number;
    public reference:string;
    public product:Product;

}

I created an add order component, src/app/order-add/order-add.component.html, that looks like this

<form (ngSubmit)="onSubmit()">
    <div class="form-group">
        <label class="col-xs-4 control-label" for="orderProduct">Product: </label>
        <div class="col-xs-8">
              <select [(ngModel)]="order.product" name="orderProduct">
                <option *ngFor="let product of products; let i = index" [value]="products[i].id" [selected]="order !== 'undefined' && products[i].id == order.product.id">
                  
                </option>
              </select>
        </div>

        <label class="col-xs-4 control-label" for="orderReference">Order Reference: </label>
        <div class="col-xs-8">
            <input type="text" style="width: 300px" class="form-control" required
                [(ngModel)]="order.reference" name="orderReference">
        </div>
        <div>
                <input type="submit" [value]="order.id !== undefined ? 'Update' : 'Create'" />
        </div>
    </div>
</form>

Below is how I define what gets loaded in src/app/order-add/order-add.component.ts ...

...
export class OrderAddComponent implements OnInit {

  public order : Order = new Order();
  public products : Array<Product>;

  constructor(public apiService: ApiService , public acRoute : ActivatedRoute) { }

  ngOnInit() {
    // Get current products list for display on order form
    this.apiService.get("products").subscribe((data : Product[])=>{
      console.log(data);
      this.products = data;
    });

    // Get info about order
    this.acRoute.params.subscribe((data : any)=>{
      console.log(data.id);
      if(data && data.id){
        this.apiService.get("orders/"+data.id).subscribe((data : Order)=>{
          this.order = data;
        });
      }
      else
      {
        this.order = new Order();
      }
    })
  }

The issue is that when my page initially loads, there are no products in my drop-down until I actually click on the select menu and attempt to load something. There is this error in the JS console that appears before anything is done ...

ERROR TypeError: Cannot read property 'id' of undefined
    at Object.eval [as updateRenderer] (OrderAddComponent.html:6)
    at Object.debugUpdateRenderer [as updateRenderer] (core.js:14735)
    at checkAndUpdateView (core.js:13849)
    at callViewAction (core.js:14195)
    at execEmbeddedViewsAction (core.js:14153)
    at checkAndUpdateView (core.js:13845)
    at callViewAction (core.js:14195)
    at execComponentViewsAction (core.js:14127)
    at checkAndUpdateView (core.js:13850)
    at callViewAction (core.js:14195)

How can I make sure my menu is pre-populated without my having to click on the SELECT menu?



from How do I pre-populate an Angular 7 menu used as an attribute of adding a component?

No comments:

Post a Comment