Last active
July 1, 2020 08:24
-
-
Save baflo/ac708c5f0c4d0c0e47c7eb96661431d6 to your computer and use it in GitHub Desktop.
Handling placeholders after delay with RxJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ng-container *ngIf="listEntities$ | async as listEntities"> | |
<div class="label-context-panel" *ngIf="listEntities.length > 0"> | |
<ul> | |
<ng-container *ngFor="let entity of listEntities"> | |
<ng-container [ngSwitch]="entity.type"> | |
<li *ngSwitchCase="'content'" [ngClass]="{ property: true, enabled: !entity.disabled }" (click)="selectReturnValue(entity)">{{ entity.propertyType }} <span class="name">{{ entity.propertyName }}</span> | |
<div [ngClass]="'tooltip'"> | |
<div class="errorHeading" *ngIf="entity.tooltip.errorHeading">{{ entity.tooltip.errorHeading }}</div> | |
{{ entity.tooltip.message }} | |
</div> | |
</li> | |
<li *ngSwitchCase="'placeholder'"> | |
<div class="placeholder" [ngStyle]="{ 'width.%': entity.width }"> </div> | |
</li> | |
</ng-container> | |
</ng-container> | |
</ul> | |
</div> | |
</ng-container> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Component({}) | |
class Test { | |
/** List entities representing placeholders that may be shown if `bitReturnValues` were received too slowly. */ | |
protected readonly loadingPlaceholders = Array.from({ length: 3 }).map(() => ({ | |
type: "placeholder" as const, | |
width: 60 + Math.floor(Math.random() * 40), | |
})); | |
/** Target for the fetched data. Contains entities to be displayed in popup list. */ | |
protected readonly bitReturnValues$ = new BehaviorSubject<Array<{ type: "content"; propertyName: string; propertyType: string }>>([]); | |
/** Show placeholders if not `bitReturnValues` were received within one second. */ | |
protected readonly showPlaceholdersTimer$ = timer(1000); | |
/** If placeholders were opened, show them for at least one second (timestamp 2000ms). */ | |
protected readonly hidePlaceholdersTimer$ = timer(2000); | |
/** List entities to render in template. This emits either placeholder entities or `bitReturnValues` */ | |
protected readonly listEntities$: Observable< | |
Array<{ type: "placeholder"; width: number } | { type: "content"; propertyName: string; propertyType: string }> | |
> = merge( | |
// Initialize with empty array. | |
of([] as []), | |
// Wait for some time, if no `bitReturnValues` were received meanwhile, emit `loadingPlaceholders`. | |
this.showPlaceholdersTimer$.pipe(takeUntil(this.bitReturnValues$), mapTo(this.loadingPlaceholders)), | |
// Try to take `bitReturnValues` until the placeholders are fed into the observable... | |
this.bitReturnValues$.pipe(takeUntil(this.showPlaceholdersTimer$)), | |
// ...in that case, wait for the minimum time after which the placeholders may be closed, or as long as | |
// it takes to receive a value, then emit the `bitReturnValues`. | |
combineLatest(this.bitReturnValues$, this.hidePlaceholdersTimer$).pipe(map(([bitReturnValues]) => bitReturnValues)) | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment