6

I was wondering if there is an easy way to count dom elements using Angular 2. For example having the following code:

    <div *ngFor="let user of users" [ngClass]="{'special': isSpecial(user)}">
        {{ user.name }}
    </div>

Is there an easy way to get the total number of rows containing the special class without creating pipes or functions?

With Jquery it would be as easy as running:

$( ".special" ).length;
Ander
  • 5,093
  • 7
  • 41
  • 70
  • 1
    Why don't you just get the user array length from you ts file? – zszep Mar 03 '17 at 20:57
  • Because that way you just get the length of the whole list, not only the elements flagged with the class special. (I have edited the question, I was using a wrong ngClass example) – Ander Mar 03 '17 at 21:01
  • have you considered using a `filter`? or `.map`? – Daniel A. White Mar 03 '17 at 21:06
  • 2
    What's login inside `isSpecial()` why don't you run this logic with `users` collection? – Hung Cao Mar 03 '17 at 21:11
  • Because that would require iterate through the list twice. That is probably fine but my question is if there is an easy way to count dom elements by class in Angular 2 – Ander Mar 03 '17 at 21:17
  • are you using angular-cli? – elmiomar Mar 03 '17 at 21:30
  • 2
    Do it in code, i'd more efficient – Günter Zöchbauer Mar 03 '17 at 21:36
  • 1
    please post the `isSpecial` function implementation. based on this code, the number of els with the special class will either be `users.length` or `0` – William B Mar 03 '17 at 21:45
  • Probably the best for performance is calculating the counter during `isSpecial()` execution as @HungCao suggested. I just though that a function doing both things kind of violates the Single Responsibility Principle (SRP), but anyway I am happy with this solution. – Ander Mar 04 '17 at 04:33

3 Answers3

5

You can use normal DOM APIs to do what you would've previously done via jQuery eg:

document.querySelectorAll('.special').length

However, unless the isSpecial(user) function is extremely expensive to run, why would querying the DOM be any more performant than just filtering the users array in code?

users.filter(u => isSpecial(u)).length

I'd caution against worrying about performance in this scenario too much without actually running some performance tests first to verify your assumptions.

snorkpete
  • 14,278
  • 3
  • 40
  • 57
0

No idea why someone downvoted this question +1

You could do something like this ..

<div #wrapper>
    <div *ngFor="let user of users" [ngClass]="{'special': isSpecial()}">
        {{ user.name }}
    </div>
<div>

Now access the #wrapper with the @ViewChild annotation in the component class.

Then finally ..

ngAfterViewInit() {
    let numSpecials = $(viewChildEl).find('.special').length;
}

Not saying this is the best solution but it is A solution that attempts to introduce as few functions as possible as requested by OP.

danday74
  • 52,471
  • 49
  • 232
  • 283
  • Would that work out of the box without installing jQuery? – Ander Mar 04 '17 at 04:33
  • Angular1 has jQuery lite built in - but I think Angular2 does not - u will prob need to bring in jQuery - but u wud prob need to anyway since so many libs depend on it - all the best :) – danday74 Mar 04 '17 at 04:35
  • PS Ive asked this question here to clarify .. http://stackoverflow.com/questions/42592180/does-angular2-have-jquery-built-in – danday74 Mar 04 '17 at 04:42
0

@Snorkpete I have been measuring performance using .filter() and .reduce():

var t0 = performance.now();
users.reduce(function(total, u){return isSpecial(u) ? total+1 : total}, 0)
var t1 = performance.now();
console.log(t1-t0);

Result: 0.04500000000007276 seconds

var t0 = performance.now();
customersActivity.filter(u => isSpecial(u)? true:false).length;
var t1 = performance.now();
console.log(t1-t0);

Result: 0.09000000000014552 seconds

In my tests .reduce() is about 2x times faster than .filter()

Ander
  • 5,093
  • 7
  • 41
  • 70
  • Same diff - the point being that it's better to 'work with' the actual array rather than querying the DOM for information about the array. Nice to know about the performance difference between filter and reduce though – snorkpete Aug 09 '18 at 09:25