-1

how can I keep track of a ngfor array, that can change via pipes ?

I have tried trackBy, making local variables, change events, but nothing does the job.

I have an array of numbers.

myArray = [2, 4, 5, 6];

this is used like this

<div *ngFor="let item of myArray">
  {{item}}
</div>

<div> totalsum: </div>

this array, I want to calculate the total sum. If I filter my list with a pipe, there might be fewer items shown.

myArray = [2, 6];

now this shorter list should be calculated.

Johansrk
  • 5,160
  • 3
  • 38
  • 37
  • 1
    What are you trying to track? What do you mean when you say "keep track of"? And what is the "job" you are trying to do? What did you try to use "trackBy", "local variables", and "change events" to do? – vince Jan 18 '18 at 20:43
  • [This](https://stackoverflow.com/questions/36322829/how-to-use-track-by-inside-ngfor-angular-2) might help you. – RockGuitarist1 Jan 18 '18 at 20:50
  • I think the question is how to reduce() the array item values to calculate the sum, but only using values present in the *ngFor at any given moment including affects of Pipes. – Alexander Staroselsky Jan 18 '18 at 21:07
  • jep.. but how. It seems I have tried all. Maybe I can make a simple pipe that saves the current array in a service. And then make an observable to notify the calculator – Johansrk Jan 18 '18 at 21:08
  • It sounds like your Pipe may be impure? As in it's mutating `myArray`? Without knowing how the Pipe works, it would be difficult to provide a solution. If you are needing to filter the list based on some criteria, it may be more straightforward to have an initial list that does NOT get modified, then functionally return a new array with only the items that should be displayed/calculated that is used in the `*ngFor`. Can you provide the code for your Pipe? – Alexander Staroselsky Jan 18 '18 at 21:25
  • I have several pipes. the above example is a simplified version of my array. Anyway It seems like my propotial works, Making a pipe that sets the count to a service. That service uses an observable – Johansrk Jan 18 '18 at 21:54

1 Answers1

0

The solution was to make a pipe on the ngfor

import { Pipe, PipeTransform } from '@angular/core';
import { InvoiceService } from 'app/components/application/invoices/invoice.service';

@Pipe({
    name: 'invoiceFilteretList'
})
export class InvoiceFilteretList implements PipeTransform {
  constructor( private invoiceService: InvoiceService ) {}

    transform(value: any, q: string, type) {
    let totalSum = 0;
    let remaining = 0;

    for (let i = 0; i < value.length; i ++) {
      totalSum += value[i].totalPrice; 

      if ( value.hasOwnProperty( 'paid' )) {
        if (!value.paid) { // if not paid
          remaining += value.totalPrice;
        }
      }

    }

    this.invoiceService.SetTotalSum( totalSum );
    this.invoiceService.SetRemainingSum( remaining );

    return value;
    }
}

then I made a service for storing the sum and remaning sum

import { ReplaySubject } from 'rxjs/ReplaySubject';

export class InvoiceService {
    public totalSum = new ReplaySubject<any>();
    public remainingSum = new ReplaySubject<any>();

  SetTotalSum( value: number ) {
    this.totalSum.next( value );
  }

  SetRemainingSum( value: number ) {
    this.remainingSum.next( value );
  }
}

and last I made a method for getting the updated sums

 filteredInvoiceList() {
    this.invoiceService.totalSum
    .subscribe(res => {
      this.filteredSum = res;
    });

    this.invoiceService.remainingSum
    .subscribe(res => {
      this.filteredSumNotPaid = res;
    });
  }

and display those in the view

Johansrk
  • 5,160
  • 3
  • 38
  • 37