Having trouble with Typescript subtraction yielding unexpected results?

If I have a total amount including VAT and want to separate the net price and the VAT value, how can this be done?

For example, if the final price is $80.60 with a VAT rate of 24%, what would be the net price and the VAT value? The correct answer should show the net price as $65.00 and the VAT value as $15.60.

I'm having an issue where typescript calculates the VAT value as 15.599999999999994 instead of rounding it to 15.60. Although there are other methods to calculate VAT, my main concern is why my code is generating this lengthy decimal.

Here is the code in question: component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-fpa',
  templateUrl: './fpa.component.html',
  styleUrls: ['./fpa.component.css']
})
export class FpaComponent implements OnInit {

    public netPrice:number;
    public fpaPercent:number=24;
    public fpaValue:number=0;
    public totalPrice:number;

public calc(calcType:string = ''){
    this.netPrice = this.totalPrice / ((this.fpaPercent/100)+1);
    this.fpaValue = this.totalPrice - this.netPrice;
}

}

component.html

                   
                        <mat-form-field>
                            <input [(ngModel)]="netPrice" (keyup)="calc('byNetPrice');" matInput placeholder="Net Price">
                        </mat-form-field>

                        <mat-form-field>
                            <input [(ngModel)]="fpaPercent" (keyup)="calc();" matInput placeholder="% Vat">
                        </mat-form-field>

                        <mat-form-field>
                            <input [(ngModel)]="fpaValue" (keyup)="calc('byFpaValue');" matInput placeholder="VAT Value">
                        </mat-form-field>

                        <mat-form-field>
                            <input [(ngModel)]="totalPrice" (keyup)="calc('byFinalPrice');" matInput placeholder="Final Price" >
                        </mat-form-field>

Answer №1

The reason for discrepancies in decimal numbers when converted to binary is due to the inherent limitations of binary encoding. It often leads to rounding errors.

To solve this issue, you can easily format the number to two decimal places.

There are multiple approaches you can take:

  • You may utilize the built-in JavaScript Number method, toFixed(2), within your controller logic to ensure the subtraction result is formatted to two decimal places. Check out the MDN docs for more information.

  • Alternatively, consider using the Angular DecimalPipe in your controller logic as shown below. Refer to the Angular documentation for detailed guidance:

    /*
        The Angular DecimalPipe provides a range of formatting options,
        allowing you to specify both minimum and maximum digits after
        the decimal point. In this scenario, we're setting it to 2 decimal
        places.
    
        To cater to regional differences in number representation,
        the DecimalPipe constructor requires a locale parameter.
    */
    const locale = 'en-US';
    const decimalPipe = new DecimalPipe(locale);
    this.fpaValue = decimalPipe.transform(this.totalPrice - this.netPrice, '.2-2');
    
  • If you intend to display the fpaValue in another section of your template, incorporate the decimal pipe directly within the template as demonstrated below:

    {{ fpaValue | number:'.2-2' }}
    

Answer №2

Initially, the issue lies not with TypeScript but with how Floating Point works in JavaScript:

To resolve this, you can utilize the following code snippet:

this.fpaValue.toFixed(2);

By doing so, you will obtain your result rounded off to 2 decimal places.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for defining a collection of strings as a data type?

Is there a way to define a strict type for a group of strings that users must adhere to? I want to restrict input to only be one of the predefined strings in the group. How can I achieve this? This is my current approach: const validTypes: Array<strin ...

The client PC running the Ionic app encountered an error while trying to load chunk 'XY'

I'm currently working with Ionic 3 and lazy loading. Everything is running smoothly on 12 different PCs. However, I encountered an issue on one PC where it started displaying the error message "Loading chunk 7 failed," sometimes with numbers like 43 o ...

parsing objects within an HTML component in Angular

Is there a way to utilize an object as the @input parameter in HTML? For example: <app-home [param]="user.salary"></app-home> However, the type of my user object is structured like this: user:Person=new Employee(); The classes invol ...

Error TRPCClient: The unexpected presence of the token "'<'", ""<!DOCTYPE "... invalidates the JSON format within Next.JS

Encountering an error in the authentication call back page: TRPCClientError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON in Next.JS. The issue occurs in src/app/auth-callback/page.tsx and here's the relevant code ...

What is the implication when Typescript indicates that there is no overlap between the types 'a' and 'b'?

let choice = Math.random() < 0.5 ? "a" : "b"; if (choice !== "a") { // ... } else if (choice === "b") { This situation will always be false because the values 'a' and 'b' are completely disti ...

Error Passing Data to Child Component in Typescript on Next.JS 14 Compilation

Although there are many similar questions, I am struggling to make my code work properly. I recently started learning typescript and am having trouble passing data to the child component. While the code runs fine in development (no errors or warnings), i ...

Unable to discontinue receiving notifications from ActionsSubject in ngrx/store

I am using ngrx/store to handle login actions by subscribing to a store. The login component is displayed as a modal, and if I enter an incorrect password, the data received is data.type === 'LOGIN_FAILED'. However, even after closing and reopeni ...

An issue has been identified with React's HTML input maxLength feature where it does not display an error

Within my form, I have an input field that currently does not include validation for a maximum length. <input type="text" className="form-control" id="company" onBlur= ...

Personalized style for text overflow property

The application is created using Angular. Within a component, we have a div containing some text: <div>abcdefghijklmnop<div> Depending on the screen size, the text should either be fully displayed or clipped. I discovered the property 'te ...

Similar to TypeScript's `hasOwnProperty` counterpart

When working with TypeScript objects, is there a way to loop through a dictionary and set properties of another dictionary similar to how it is done in JavaScript? for (let key in dict) { if (obj.hasOwnProperty(key)) { obj[key] = dict[key]; } } If ...

Ionic causing delay in updating ngModel value in Angular 2

My ion-searchbar is set up like this: <ion-searchbar [(ngModel)]="searchQuery" (keyup.enter)="search();"></ion-searchbar> In the typescript file, the searchQuery variable is defined as follows: export class SearchPage { searchQuery: string ...

Merge MathJax into SystemJS compilation

I utilize SystemJS to construct an Angular 2 project and I am interested in incorporating MathJax into a component. To start using it, I executed the following commands: npm install --save-dev mathjax npm install --save @types/mathjax Now, I have success ...

Tips for dynamically calling a property member of a function type in Typescript

How can I determine if a member is a function in TypeScript? Is dynamic typing discouraged in TypeScript? function checkIfFunction<T, K extends keyof T>(obj: T, propName: K) { if (typeof obj[propName] === "function") { obj[p ...

The module X is experiencing a metadata version mismatch error. Version 4 was found instead of the expected version 3 while resolving symbol Y

I am in the process of creating an Angular 4 application using angular-cli (ng build) and incorporating ngx-clipboard. Recently, I have encountered a sudden error that has persisted for a few days despite there being no changes to my source code: ERROR in ...

Utilizing a service within NestJS

I'm currently in the process of updating some older code and I have created a service that I want to inject into the constructor of a class. There are two key points to consider about this particular class. The first point is that it is instantiated b ...

Navigating in Angular 2 RC4 with Path Variables Containing Special Symbols

Could someone offer suggestions on how to correctly call parameters with special characters from URLs? Below is my current code for calling the parameter: ngOnInit() { this.route.params.subscribe(params => { let accountrefID = params ...

What is the best design for an Angular side menu?

Seeking guidance on creating a side menu for an Angular project using Firebase data. Uncertain about the architecture. Created a component with the selector app-serie-list: <li routerLinkActive="active" *ngFor="let serie of series; let i = index"> ...

Display the length of the product array when I have multiple JSON objects

I am working with the following JSON data: { "StatusCode": 0, "StatusMessage": "OK", "StatusDescription": [ { "_id": "12123", "dateCreated": "2019-12-03T13:45:30.418Z", "pharmacy_id": "011E7523455533 ...

Navigating to a specific section

Just a heads up: I'm relatively new to Angular, so there's a possibility that my understanding might be off and therefore my question may not make sense. I've recently started working on an application that requires several intricate featur ...

Rendering illuminated component with continuous asynchronous updates

My task involves displaying a list of items using lit components. Each item in the list consists of a known name and an asynchronously fetched value. Situation Overview: A generic component named simple-list is required to render any pairs of name and va ...