Reputation: 31
Requirement
There are a list of items in the shopping cart. Each item has option, quantity, price. Need to calculate the price based on change in quantity and option of a item.
Research I had added [(ngModel)] as below, so as to use 2 way data-binding, however, no idea why the page simply keeps on loading and than crashes without any error. When i remove the ngModel attribute the page loads successfully.
<span class="price col-1 pull-right" >{{ orderType*price}}</span>
<div class="qty" style="margin:0;">
<span class="spinner">
<span class="sub">-</span>
<input type="number" id="qty" name="qty" min="1" max="100"
value="1" class="qty-spinner" [(ngModel)]="quantity" />
<span class="add">+</span>
</span>
</div>
<div class="type">
<label class="radio inline" *ngFor="let option of item.options; let k = index">
<input id="{{'toggle-half-'+item.id+'-'+j}}" type="radio"
name="{{'option-toggle-'+item.id+'-'+j}}" [value]="option.value"
[checked]='k===0' [(ngModel)]="orderType" />
<span>{{option.title}} </span>
</label>
</div>
TypeScript Code
quantity:number;
orderType:number;
price:number;
constructor() {
this.quantity = 1;
this.price = 0;
}
Controls used
1) Number Control input of type number for quantity.
2) Radio Control for Options [Half/Full]
3) span element for printing calculated price.
Expected Output
Price which is currently set to 0 should get updated when we change the quantity or the option.
Eg. Value set for option [Half] = 10
Eg. Value set for option [Full] = 20
Please advise how can i implement this, is the above logic and implmentation correct ?
Thanks in advance
Upvotes: 2
Views: 3587
Reputation: 31
the issue is resolved now. The code snippet in the description was implemented between a div tag which had a *ngFor directive, that iterated through the list of items.
Issue
For dividing the list of items into 2 columns "div.col-md-6", i had implemented a a function that returned me an array of 2 arrays each containing set of items, so as to iterate through each array and display the items in each column.
Could not find the issue, why there was an issue only when i implemented the ngModel tag, which should have not been the case. However, i removed that splitting function and everything worked fine for me.
Thanks to all for your efforts and help.
Upvotes: 0
Reputation: 4928
Not sure why it crashed but if i were you. The constructor
constructor() {
this.quantity = 1;
this.price = 0;
}
I will use ngInit instead since its a two way binding.
import { OnInit } from '@angular/core';
export class myClas implements OnInit {
ngOnInit() {
this.quantity = 1;
this.price = 0;
}
}
Secondly, you have value in your radio button and input type number. Are you sure they return value of type number ? If i were you i will use or try string first and cast it to my desired number type afterward. Or use a pipe. Wrong type conversion can be expensive sometimes . So can you try
quantity:string;
orderType:string;
price:string;
first and do your number conversion afterward ?
Upvotes: 0
Reputation: 3791
Edit: Reviewing the documentation sample shared in jkris' answer, value
makes sense for radio inputs. I still suspect checked
creates an update loop when combined with [(ngModel)]
.
I notice you're binding checked
in addition to the NgModel binding. If you remove it, does it keep the correct behavior and prevent crashing?
<input type="number" class="qty-spinner" min="1" max="100"
name="quantity" [(ngModel)]="quantity" />
<input type="radio"
[value]="option.value" name="option" [(ngModel)]="option" />
Otherwise, another option is to use [checked]
and (click)
(or similar) bindings in place of NgModel.
Upvotes: 0
Reputation: 6541
The variable option
is already in use in the ngFor
directive. See line:
<label class="radio inline" *ngFor="let option of item.options; let k = index">
Use a different variable instead for the ngModel
, example:
<input id="{{'toggle-half-'+item.id+'-'+j}}"
type="radio"
name="{{'option-toggle-'+item.id+'-'+j}}"
[value]="option.value"
[(ngModel)]="selectedOption" />
Look at the examples in the documentation;
EDIT
Also you have you're binding the checked
attribute while imposing a ngModel
. Instead of doing that, simply init the ngModel
with the value you want, in your case,
selectedOption = item.options[0].value
Upvotes: 0