I work with Angular 6. I have a form with 4 fields. Two of them are the price and the quantity. I want to display in another field the multiplication of price and quantity.
I defined an attribute directive. I want to display in a div the field of directive paModel totalPrice. I defined an event in the form fields.
This is my form
<form novalidate [formGroup]="form" (ngSubmit)="submitForm(form)">
<div class="form-group" *ngFor="let control of form.productControls">
<label>{{ control.label }}</label>
<input
class="form-control"
[(ngModel)]="newProduct[control.modelProperty]"
name="{{ control.modelProperty }}"
formControlName="{{ control.modelProperty }}"
[paModel]="newProduct[control.modelProperty]"
(paModelChange)="newProduct[control.modelProperty] = $event"
[pa-product]="newProduct"
#paModel="paModel"
/>
<ul class="text-danger list-unstyled" *ngIf="(formSubmitted || control.dirty) && !control.valid">
<li *ngFor="let error of control.getValidationMessages()">{{ error }}</li>
</ul>
</div>
<div class="bg-primary text-white">{{ paModel.totalPrice }}</div>
<button
class="btn btn-primary"
type="submit"
[disabled]="formSubmitted && !form.valid"
[class.btn-secondary]="formSubmitted && !form.valid"
>
Create
</button>
</form>
The attribute directive name is paModel. This is my paModel directive
import { Input, Output, EventEmitter, Directive, HostBinding, HostListener, SimpleChange } from "@angular/core";
import {Product } from "./product.model"
@Directive({
selector: "input[paModel]",
exportAs: "paModel"
})
export class PaModel {
direction: string = "None";
@Output("pa-totalprice")
totalPrice: number = 0;
@Input("paModel")
modelProperty: string;
@Input("pa-product")
product: Product;
@HostBinding("value")
fieldValue: string = "";
ngOnChanges(changes: { [property: string]: SimpleChange }) {
console.log("en ngOnChanges");
let change = changes["modelProperty"];
if (change.currentValue != this.fieldValue) {
this.fieldValue = changes["modelProperty"].currentValue || "";
this.direction = "Model";
this.totalPrice = 0;
}
}
@Output("paModelChange")
update = new EventEmitter<string>();
@HostListener("input", ["$event.target.value"])
updateValue(newValue: string) {
console.log("en updateValue");
console.log("name ",this.product.name)
console.log("price ",this.product.price)
console.log("quantity ",this.product.quantity)
if (this.product.price != undefined && this.product.quantity != undefined) {
this.totalPrice = this.product.price * this.product.quantity;
} else {
this.totalPrice = 0;
}
this.fieldValue = newValue;
this.update.emit(newValue);
this.direction = "Element";
}
}
In the console I see the error
ERROR TypeError: Cannot read property 'totalPrice' of undefined
at Object.eval [as updateRenderer] (ProductFormComponent.html:18)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:10879)
at checkAndUpdateView (core.js:10255)
at callViewAction (core.js:10491)
at execComponentViewsAction (core.js:10433)
at checkAndUpdateView (core.js:10256)
at callViewAction (core.js:10491)
at execComponentViewsAction (core.js:10433)
at checkAndUpdateView (core.js:10256)
at callWithDebugContext (core.js:11143)
How can I display the field totalPrice in a div?
EDITED
I modified my code. Now I have the html
<div class="form-group bg-info text-white p-2">
<input class="bg-primary text-white" [(paModel)]="newProduct" #paModel="paModel" />
<div *ngIf="paModel" class="bg-primary text-white">Total Price : {{ paModel.totalPriceString }}</div>
</div>
And I have two methods
ngOnChanges(changes: { [property: string]: SimpleChange }) {
let change = changes["modelProperty"];
/* if (change.currentValue != this.fieldValue) { */
this.fieldValue = changes["modelProperty"].currentValue || "";
this.direction = "Model";
if (this.product.price != undefined && this.product.quantity != undefined) {
this.totalPrice = this.product.price * this.product.quantity;
} else {
this.totalPrice = 0;
}
this.totalPriceString = this.totalPrice.toString();
/* } */
}
@Output("paModelChange")
update = new EventEmitter<string>();
@HostListener("input", ["$event.target.value"])
updateValue(newValue: string) {
if (this.product.price != undefined && this.product.quantity != undefined) {
this.totalPrice = this.product.price * this.product.quantity;
} else {
this.totalPrice = 0;
}
this.fieldValue = newValue;
this.update.emit(newValue);
this.direction = "Element";
this.totalPriceString = this.totalPrice.toString();
}
At the end of these methods totalPrice has the multiplication, but the values is no displayed in the div.
How can I fix this?