Cannot read property 'stock' of undefined

431 views Asked by At

I am making an Angular app where I want to update the value of stock-based on the input that the user enters.

// app.component.ts

export class AppComponent implements OnInit{
    title = 'Products';
    products = [];
    productToUpdate;

    ngOnInit() {
      this.products = this.getProducts();
    }

    getProducts() {
      return [
        { 'id' : '1', 'title' : 'Screw Driver', 'price': 400, 'stock' : 11},
        { 'id' : '2', 'title' : 'Nut Volt', 'price': 200, 'stock' : 5},
        { 'id' : '3', 'title' : 'Resistor', 'price': 78, 'stock' : 45},
        { 'id' : '4', 'title' : 'Tractor', 'price': 20000, 'stock' : 1},
        { 'id' : '5', 'title' : 'Roller', 'price': 62, 'stock' : 15},
      ]
    }

    changeStockValue(p) {
      console.log(p)
      this.productToUpdate = this.products.find(this.findProducts, [p.id])
      console.log(this.productToUpdate)
      this.productToUpdate['stock'] = this.productToUpdate['stock'] + p.updatedstockvalue;

      console.log(this.productToUpdate)
    }

    findProducts(p) {
      return p.id == this[0]
    }
  }
<!-- app.component.html -->

<div class="container">
    <br>
    <h1 class="text-center">{{title}}</h1>
    <table class="table">
        <thead>
            <th>Id</th>
            <th>Title</th>
            <th>Price</th>
            <th>Stock</th>
        </thead>

        <tbody>
            <tr *ngFor="let p of products">
                <td>{{p.id}}</td>
                <td>{{p.title}}</td>
                <td>{{p.price}}</td>
                <td>{{p.stock}}</td>
                <td><app-stock-status [productId]='p.id' [stock]='p.stock' (stockValueChange)='changeStockValue($event)'></app-stock-status></td>
            </tr>
        </tbody>
    </table>
</div>

// stock-status.component.ts

export class StockStatusComponent implements OnChanges {
  
    @Input() stock; number;
    @Input() productId: number;
    @Output() stockValueChange = new EventEmitter();
    color = '';
    updatedstockvalue: number;

    constructor() { }

    ngOnInit() {
    }

    stockValueChanged() {
      this.stockValueChange.emit(JSON.stringify({
      id: this.productId,
      updatedstockvalue: this.updatedstockvalue
    }))

      this.updatedstockvalue = null;
    }

    ngOnChanges() {

      if(this.stock > 10) {
        this.color = 'green';
      } else {
        this.color = 'red';
      }
    }

  }
<!-- stock-status.component.html -->

<input type='number' [(ngModel)] = "updatedstockvalue" />
    <button class="btn btn-primary" [style.background]='color' (click)="stockValueChanged()">Chnage Stock 
    Value</button>

What I am trying to do here is first display the product detail in app-root and then update the value of the stock of product by the value that thee user enters.

I have a Parent Child relation as follows:

app-stock-status -> app-root (Child to Parent Relation) as passes the stockValueChange Object to app-root

app-root -> app-stock-status (parent to Child Relation) as app-root passes 'stock' & 'productId' to app.stock-status

and I have a 'Change stock value' button in which when clicked should change the value of the stock field of the appropriate product selected. But what happens is that when I click the 'Change stock value' button it gives me an error on line 32 of app.component.ts and I am not able to update the value of the stock.

AppComponent.html:18 ERROR TypeError: Cannot read property 'stock' of undefined at AppComponent.changeStockValue (app.component.ts:31) at Object.eval [as handleEvent] (AppComponent.html:18) at handleEvent (core.js:43993) at callWithDebugContext (core.js:45632) at Object.debugHandleEvent [as handleEvent] (core.js:45247) at dispatchEvent (core.js:29804) at core.js:31837 at SafeSubscriber.schedulerFn [as _next] (core.js:35379) at SafeSubscriber.__tryOrUnsub (Subscriber.js:185) at SafeSubscriber.next (Subscriber.js:124)

Can somebody suggest what's wrong here?

1

There are 1 answers

0
Michael D On

Is there a specific reason for the convoluted use of JS find here? Based on the info you've provided the following should probably solve the issue

changeStockValue(p) {
  console.log(p);
  this.productToUpdate = this.products.find(product => product == p.id); // <-- use an arrow function for the condition
  console.log(this.productToUpdate);
  this.productToUpdate['stock'] = this.productToUpdate['stock'] + p.updatedstockvalue;

  console.log(this.productToUpdate);
}