Search code examples
htmlangulartypescriptangular12

Number pipe number : '1.2-2' is not working while using by a ternary inside *ngFor directives


I was working on a project using Angular 12. At some stage, I needed to render an array of objects which I got from the API. In each object, I have some fields of numbers like CostPrice, TradePrice, MRP, SellingPrice.

My target is to render those and view those inside the input tag. I have a variable named forViewDetails, based on which I was trying to make the field read-only. Inside the value attribute, I have binded the fields using attribute binding. There I was rendering the prices based on the forViewDetails option. If it is true then the values will appear with two decimal points. That's why I have used the number pipe inside a bracket. Else it will appear without points.

But the thing is it's working for CostPrice and TradePrice. But for MRP and TradePrice it's not working. If I remove the pipe from them, then it works. But after adding pipe the fields become empty. I thought maybe I am not getting the number in those fields. But I checked those, those were numbers.

I am attaching the code samples below. Any solution or suggestion is highly appreciated.

The output I am getting using pipe:

enter image description here

The output after removing the pipe from MRP:

enter image description here

<!-- trade price -->
<td style="width: 100px">
  <input
    [readonly]="forViewDetails"
    id="itemTp_{{ i }}"
    type="number"
    min="0"
    class="form-control w-100"
    [value]="forViewDetails ? (item.TradePrice | number : '1.2-2') : item.TradePrice"
    (input)="tpChanged(i, item, $event)"
    (keyup.enter)="nextInput('tp', $event)"
    [ngClass]="{ 'is-invalid': submitted && item.TradePrice == 0 }" />
</td>



<!-- mrp -->   
<td style="width: 100px">
  <input
    [readonly]="forViewDetails"
    id="itemMrp_{{ i }}"
    type="number"
    min="0"
    class="form-control w-100"
    [value]="forViewDetails ? (item.MRP | number : '1.2-2') : item.MRP"
    (input)="mrpChanged(i, item, $event)"
    (keyup.enter)="nextInput('mrp', $event)"
    [ngClass]="{ 'is-invalid': submitted && item.MRP == 0 }" />
</td>
//object I am getting
{
    Barcode: "B-090807",
    BrandId: "BRD00002",
    CategoryId: "SUBCAT0100",
    CompanyId: "COM00002",
    CostPrice: 900,
    Discount: 0,
    ExpDate: "2050-05-14",
    Id: 8,
    MRP: 1200,
    MinShelfLife: 9999,
    PVAT: 0,
    ProductGrossWeight: 0,
    ProductId: "PRD1671704018388",
    ProductMargin: 0,
    ProductName: "Hilsha Fish",
    ProductNetWeight: 0,
    ProductQty: 50,
    ProductUnit: "kg",
    SellingPrice: 1200,
    StockReceivedId: "SR-1672203680930",
    SupplierId: "SUP00002",
    TAX: 0,
    TradePrice: 900,
    VAT: 0,
}

My target is to achieve all values in decimal form with two fraction points after it as I am getting in CostPrice and TradePrice.


Solution

  • The reason why it is not showing is due to the MRP value exceeding a thousand, with the Number pipe will display as "1,000.00" (with thousand separator), and the <input type="number" /> doesn't allow for the comma character.

    In order to solve it, you should do either of these:

    1. Not apply the number pipe to format the value in <input type="number" />
    2. Implement a custom pipe to remove the comma character.
    <input
      [value]="forViewDetails ? (item.MRP | number: '1.2-2' | noComma) : item.MRP"
    />
    
    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({ name: 'noComma' })
    export class NoCommaPipe implements PipeTransform {
      transform(value: any, ...args: any[]) {
        return value.toString().replace(/,/g, '');
      }
    }
    

    Demo @ StackBlitz

    1. Use <input type="text" /> instead to allow displaying the formatted number with thousand separator.