Roka545
Roka545

Reputation: 3626

Get sum of property values from an observable array

I have an observable array and would like to get the sum of a property values in that array. My array is defined as:

public bookStores$: Observable;

I was going to do a simple for loop and calculate the sum, but I get a syntax error when trying to use the count property of my array:

Operator '<' cannot be applied to types 'number' and '<T>(this: Observable<T>, predicate?: (value: T, index: number, source: Observable<T>)=>boolean)...

This occurs when I do:

for (let i = 0; i < this.bookStores$.count; i++){ }

Every item in my array of BookStore objects has a property called numberOfBooks. What is the proper way to get the sum of those values contained on each BookStore object in my BookStore array?

Upvotes: 0

Views: 501

Answers (1)

JGFMK
JGFMK

Reputation: 8904

This is why you're getting unexpected results for Observable.count
To get the array lenght of the results, you need to do, something like this:

BookStoreService.ts

...
getBookStore() : Observable<Bookstore> {
   this.bookstore$ = this.http.get(...)
      .map( (response:Response) =>  response.json() )
      .map( response => response.bookstore);  // optional depends if JSON payload you want is wrapped inside some other container
   return this.bookstore$;
}

Component.ts

  ...
  bookstore$ : Observable<Bookstore>;
  bookstores: Bookstore[];
  numberOfBookStores:number;
  constructor(private bookService:BookService) {}

   ..
  this.bookService.getJobs()
   .subscribe(
     bookstores => {this.bookstores = bookstores;
                    this.numberOfBookstores = this.bookstores.length;
                   },
     err       => { this.bookstores = [] as BookStore[];
                    // Caters for 404 etc error - be sure to be more robust in final code as you may want to indicate types of error back to user. 
                  },
     ()        => {
                  }
   );

Update:
If you only need to loop through the list in yourHTML template, then then defining the bookstores array as a property would not be necessary. I did this to illustrate how to get the size of the returned collection of bookstores.

You can use this type of syntax:

<tr *ngFor="let bookstore of (bookstore$ |async) as bookstores; 
            trackBy bookstore?.id; let i = index">
  <td>{{bookstore.numberofBooks}}
<tr/>

You can find out more about:

Furthermore have a look at libraries like Lodash and Underscore for summing count of number of books. I've not used Underscore myself. Here's a simple example to get you started.

If you want to get more adventurous have a look at this Functional Programming in Javascript Tutorial

Upvotes: 1

Related Questions