Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular TypeError: is not a function when trying to call an object.object[].method

I am getting the following error when I tried to call a method of an object.object[].method in angular 4:

OrderComponent.html:30 ERROR TypeError: item.increaseQuantity is not a function at OrderComponent.increaseQuantity (order.component.ts:87)

The typescript code I have is below. When I call the OrderComponent.IncreaseQuantity(itemLoc: number) method, it generates the error above when I try to call this.orderItems[itemLoc].increaseQuantity() method within the method. I don't know why it does not know the OrderItem.increaseQuantity method:

import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';

class OrderItem {
    id: number;
    name: string;
    unitPrice: number;
    quantity: number;
    amount: number;
    comment: string;

    increaseQuantity(): boolean {
        console.log("In the Order Item itself - worked.");
        this.quantity += 1;
        this.amount = this.quantity * this.unitPrice;
        return false;
    }
}

class Order {
    id: number;
    createdTime: Date;
    orderType: string;
    tableName: string;
    orderItems: OrderItem[];
}

@Component({
    selector: 'order',
    templateUrl: './order.component.html'
})
export class OrderComponent {
    public order: Order;
    public total: number = 0;


    constructor(http: Http, @Inject('ORIGIN_URL') originUrl: string) {
        http.get(originUrl + '/api/Order/2').subscribe(result => {
            this.order = result.json() as Order;
            this.updateTotal();
        });

    }

    updateTotal(): void {
        this.total = 0;
        //console.log("all: " + JSON.stringify(this.order.orderItems));
        this.order.orderItems.forEach(s => this.total += s.amount);
    }

    increaseQuantity(itemLoc: number): boolean {
        //item.increaseQuantity();
        let item = this.order.orderItems[itemLoc] as OrderItem;

        console.log("This increaseQuantity work." + JSON.stringify(item));

        return item.increaseQuantity();
        //return false;
    }

}
like image 750
tazza Avatar asked Aug 03 '17 03:08

tazza


Video Answer


1 Answers

You never instantiate any Order or OrderItem instances. Just doing

this.order = result.json() as Order

or

let item = this.order.orderItems[itemLoc] as OrderItem;

does not result in those instances automagically being created, so you end up calling your methods on pure data objects (i.e. the one parsed from JSON). Those objects do not have those instance methods defined, which results in the error you're seeing.

Instead you'd have to do something like:

const orderData = result.json();

const order = new Order();
order.id = orderData.id;
// ... assign rest of properties
order.items = orderData.orderItems.map(orderItemData => {
    const orderItem = new OrderItem();
    orderItem.id = orderItemData.id;
    // ... assign rest of properties

    return orderItem;
});

this.order = order;

Creative use of utility functions, constructors and interfaces can be used to render the above more succinct, but in essence, this is what needed.

like image 103
Robby Cornelissen Avatar answered Oct 18 '22 10:10

Robby Cornelissen