Clarity: Datagrid with *clrDgItems and async pipe does not allow to access the resolved observable

Created on 26 Sep 2020  路  5Comments  路  Source: vmware/clarity

Describe the bug

When using the datagrid in combination with Angular's async pipe one can only access the resolved observable value when using *ngFor.

<clr-dg-row *ngFor="let record of (records$ | async) as records" [ngClass]="{'myCss': doSomethingWithRecords(records)}">

With *clrDgItems the resolved observable is undefined.

<clr-dg-row *clrDgItems="let record of (records$ | async) as records" [ngClass]="{'myCss': doSomethingWithRecords(records)}"> -> records is always undefined.

How to reproduce

Steps to reproduce the behavior:

  1. Go to https://stackblitz.com/edit/clarity-v4-light-theme-vavtsw?file=src/app/app.component.ts
  2. Have a look at the first datagrid using *ngFor
  3. The second datagrid with *clrDgItems causes an error, since the resolved observable is undefined.
  4. See error message on the console.

Expected behavior

According to the documentation on smart iterators,

they have the exact syntax and behave the same way

Therefore I expected that *clrDgItems also allows to access the resolved observable.

Versions

App

  • Angular: 10.0.1
  • Clarity: 4.0.0
@clangular datagrid has workaround under consideration bug

All 5 comments

The grouping operator seems to be changing the order of execution in a way that *clrDgItems isn't aware of. It seems like a lifecycle issue and how we instantiate the NgForOf iterator under the hood. Something is different from the native *ngFor directive.

A workaround that might help is to remove the grouping operator and the casting as records. Perhaps there is another way to access the records array for setting the correct class?

https://stackblitz.com/edit/clarity-v4-light-theme-f5skfb

Thanks for the investigation.

I'm afraid that the suggested solution doesn't solve the issue, since the observable - in this case a BehaviorSubject - does not allow to directly access its content. If you add console.log(prev) to the areRecordsOnDifferentDays method and open the clrDgItems tab, the console always prints undefined.

I've been able to work around this issue by handling the subscription in the component logic, store the resolved observable result in a separate variable and pass it to clrDgItems.

Is this planned for v5?

A simple solution is to put an *ngIf on a parent element as such

<div *ngIf="itemsObservable | async as items">
  <div *ngFor="let item of items">
    ...
  </div>
</div>

Stackblitz solution

Thanks @ConnerEnders <3

Not being a front-end dev by default, your solution was what I missing, but also neatly worked around the problem for me. Where I was struggling was that I had two separate instantiations of the observable in my component template, so it was still throwing errors; I didn't know you could declare a variable then use it later. I ended up with this:

<div *ngIf="itemsObservable | async as items">
  <div *clrDgItems="let item of items">
    ...
  </div>
</div>

No more errors, thanks!

Was this page helpful?
0 / 5 - 0 ratings