How to calculate the sum of all values in a FormArray in Angular

I am trying to retrieve the input values from each row and then calculate the sum of these rows.

Here is my HTML code:

<ng-container formArrayName="cap_values">
    <tbody *ngFor="let item of capValues.controls; let i=index" [formGroupName]="i">
        <tr>
            <td class="freeze-first-col"><input type="text" (blur)="getName(item.value.name)" formControlName="name"></td>
            <td><input type="number" formControlName="fdnTotalShares"></td>
        </tr>
    </tbody>
</ng-container>

This is how my .ts file looks like:

ngOnInit() {
  this.form = this.fb.group({
    cap_values: this.fb.array([this.fb.group({
      name: '',
      fdnTotalShares: '',
    }
    )])
  })
}

I'm looking for a way to loop through each value in the array and calculate the total sum. I've heard about using .valueChanges, but I'm still not sure how to implement it properly.

Answer №1

There are several ways to achieve this task, here are a few options:

Method 1:

get sumValues(): FormArray {
    return this.form.get('sum_values') as FormArray;
}

calculateSum() {
    this.total = this.sumValues.value.reduce((previous, current) => previous + +current.fdnTotalShares, 0);
    // OR
    // this.total = this.sumValues.getRawValue().reduce((previous, current) => previous + +current.fdnTotalShares, 0);
}

Note the use of the + sign in +current.fdnTotalShares. This is intentional to ensure proper addition of numbers (assuming fdnTotalShares will always be numeric) instead of string concatenation.

Method 2:

this.total = 0;
this.sumValues.value.forEach(item => {
      this.total += +item.fdnTotalShares;
});

If needed, you can replace value with getRawValue() for computations that involve disabled controls.

Here is a stackblitz example illustrating this approach (including the impact of enabled and disabled controls).

UPDATE: Responding to your query in the comments, here's another example similar to the sum calculation mentioned earlier:

multiplyAndSave() {
    const productResult = this.sumValues.value.reduce((previous, current) => previous * +current.fdnTotalShares, 1);
    // Provided the "formControlName" for the input storing the multiplication result is 'multiplyResult'
    this.form.get('multiplyResult').setValue(productResult);
    // Alternatively, you can use "patchValue" method instead of "setValue"
    // this.form.get('multiplyResult').patchValue(productResult);
}

I have also updated the stackblitz example to demonstrate this operation.

Trust this explanation clarifies things for you.

Answer №2

Utilize the valueChanges Observable to accomplish this task.

In the component, after creating the form, subscribe to the valueChanges within the array named cap_values.

import { Subscription } from 'rxjs';

total: number = 0;
subscription: Subscription;

ngOnInit() {
    // Form creation logic goes here

    this.subscription = this.capValues.valueChanges.subscribe(data => {
        this.total = data.reduce((a,b) => a + +b.fdnTotalShares, 0)
    });
}

get capValues() {
    return this.form.get('cap_values') as FormArray;
}

To display the total in your template dynamically based on changes in the fdnTotalShares input, simply use {{total}}.

Make sure to unsubscribe from the valueChanges to prevent memory leaks. This is handled by using the subscription variable introduced earlier in the code snippet above.

ngOnDestroy() {
    this.subscription.unsubscribe();
}

Check out a basic implementation example on StackBlitz.

Answer №3

Iterating through form controls is a common task

let sum = 0;
form.elements.forEach(item => {
  sum += item.quantity.value;
})

Use console log to ensure the correct form control is being accessed

Answer №4

Attempting a Solution Here

 console.log(this.form.length);
 console.log(this.form.value);

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

Querying multiple attributes in express-restify-mongoose

Issue: I am attempting to send a query from my Angular2 frontend to my Node.js server using express-restify-mongoose. The goal is to search for data based on multiple attributes, instead of just one. Current Working Solution: let regex = '{"title": ...

Why is this chip-list not functioning properly in my Angular 14 and Angular material application?

I'm currently developing a form using Angular 14. My goal is to incorporate a field with Angular Material chips. Within the component's Typescript file, I have the following code: constructor(private fb: FormBuilder,) { } public visible: boole ...

Communicating Data Between Controllers in Node.js

Within my PlantsController, I extract the Plants using the following method: function getAll() { const plants= HttpRequestPromise.get(config.ApiURL+'allPlants', config.head); return plants; } export class PlantsController { ... public ...

Setting up Firebase push notifications in a NativeScript Angular application is a straightforward process

I am in the process of developing an app using Nativescript, Angular, and Firebase to enable push notifications. I am utilizing the nativescript-plugin-firebase plugin as per their guidelines which state that firebase.init should be called onInit. However, ...

Downloading a CSV file using Angular 8 and Django RestFramework

I am a beginner in Angular and I'm looking to implement a feature where users can download a CSV file upon clicking a download button. Django viewset @action(detail=False, methods=['get']) def download_csv(self, request): data = { ...

Angular Pipe displays values properly, but ngFor fails to render them

I am using a pipe to filter my ngFor loop with exact matches that are passed through by clicking on the filter argument. Below is the code for my pipe: transform(values: any[], criteria: string, group): any[] { if (!values) { ...

Using TypeScript to Load JSON Data from a Folder

I'm a newcomer to TypeScript and encountering an issue. My task involves dynamically loading objects from a directory that houses multiple JSON files. The file names are generated through an export bash script populating the resource directory. I wan ...

Angular not successfully passing ID in for loop

I am trying to pass the res[i].id value to my ArrayList while maintaining the sequence. Can anyone help me understand why 809 and 806 are not getting added to the arrayList correctly? 0: {id: 0, ArrayListID: 809, VarName: "TEST001A"} 1: {id: 0, ...

Using Typescript in NextJS 13 application router, implement asynchronous fetching with async/await

Recently, I implemented a fetch feature using TypeScript for my NextJS 13 project. As I am still getting familiar with TypeScript, I wanted to double-check if my approach is correct and if there are any potential oversights. Here is the code snippet from ...

Discovering ways to align specific attributes of objects or target specific components within arrays

I am trying to compare objects with specific properties or arrays with certain elements using the following code snippet: However, I encountered a compilation error. Can anyone help me troubleshoot this issue? type Pos = [number, number] type STAR = &quo ...

What is the best way to automatically focus on my input when the page loads?

My Angular application has a 'slider' component that loads 3 child components utilizing ng-content. The first child component contains a form, and I am trying to focus on the first field upon page load. Despite setting up ViewChild correctly to r ...

The ngModel in Angular 2 does not update when a selection is made

Two select options are available, where the second one is dependent on the first: <div class="form-group"> <label class="col-xs-12 col-sm-2 control-label">Vehicle Type:</label> <div class="col-xs-12 col-sm-10"> ...

Context API is failing to work in components that use children when the version is v16.6.0 or higher

Currently, I am utilizing the latest context API of React (v16.6.0 or higher) by specifying the public static contextType inside the component that consumes the context. Everything works smoothly unless the component declaring the Provider directly include ...

Creating an Angular form from scratch using HTML

I've developed a component named login. Initially, I created an HTML form called login.component.html and then decided to convert it into an Angular form. To achieve this, I inserted <form #loginform="ngForm"> in the login.component.ht ...

Is there a way to efficiently load the json files only upon clicking the corresponding language button?

Currently, I am using a tutorial on implementing translations in Angular2. The implementation works well, but I would like to optimize it by loading json files only when the associated language button is clicked. Can someone assist me with this? // app/tr ...

Retrieving JSON data in Angular 2

There are limited options available on SO, but it seems they are no longer viable. Angular 2 is constantly evolving... I am attempting to retrieve data from a JSON file in my project. The JSON file is named items.json. I am pondering if I can achieve th ...

Strange problem encountered when transferring data to and from API using Typescript and Prisma

I'm encountering a strange issue that I can't quite pinpoint. It could be related to mysql, prisma, typescript, or nextjs. I created the following model to display all product categories and add them to the database. Prisma Model: model Product ...

Why does TypeScript struggle to accurately deduce the return type when provided with certain parameter values?

I have a function that uses a switch case to return different results depending on the input. The function, called "getTimeAgo," takes in two parameters: "date" (which can be either a Date object or a string) and "mode" (which can only be either "days" or ...

Unable to display custom component on app.component.html

After creating a unique custom component named core.component, I proceeded to import it into a module with the same name. core.component.html <div class="container-fluid text-left"> <div class="row rows-cols-2 top-bar"> ...

Struggling to accurately convert the string into a date object

I have an array of objects structured like this: const days = [ { _id: 12312323, date : '30/12/2021', dateStatus : 'presence' }, ... ] I am looking to convert the date property from a string to a Date object using the follo ...