Added debounceTime(0) since without it my changes were not reflected to the ui properly, additionally benefit was combineLatest optiomization but it broke my unit tests.
get nativeWindow(): Window {
return window;
}
private resize$ = fromEvent(this.nativeWindow, 'resize').pipe(
debounceTime(50),
map(event => event.target as Window),
startWith(this.nativeWindow),
untilDestroyed(this)
);
protected dimensions$: Observable<{ width: number; height: number }> = combineLatest([this.resize$]).pipe(
withLatestFrom(this.elementRef$),
debounceTime(0),
map(([, ref]) => ({ width: ref.nativeElement.offsetWidth, height: ref.nativeElement.offsetHeight })),
filter(dim => dim.width > 0)
);
Example unit test which worked before. I'm using @ngneat/spectator
it('should display cropped image', () => {
host.setHostInput({
assetCrop: {
type: 'CROP',
x: 100,
y: 100,
width: 200,
height: 200
}
});
expect(crop?.backgroundPosition).toBe('-100px -100px');
expect(crop?.backgroundSize).toBe('1000px 1000px');
});
I tried with fakeAsync and tick as well as whenStable but no successfully
So after investigating a problem it seems that the problem was without debounceTime(0)
the stream tried to get dimensions before the resizing process finished. Adding setTimeout made it work but I'm not satisfied with the solution.
ngAfterViewInit(): void {
setTimeout(() => {
this.#imageWrapperDimensions$.next({
width: this.elementRef.nativeElement.offsetWidth,
height: this.elementRef.nativeElement.offsetHeight
});
});
}
private resize$: Observable<{ width: number; height: number }> = this.ngZone.runOutsideAngular(() =>
fromEvent(this.window, 'resize').pipe(
debounceTime(50),
map(event => event.target as Window),
startWith(this.window),
map(() => ({ width: this.elementRef.nativeElement.offsetWidth, height: this.elementRef.nativeElement.offsetHeight })),
untilDestroyed(this)
)
);
#imageWrapperDimensions$ = new Subject<{ width: number; height: number }>();
protected imageWrapperDimensions$: Observable<{ width: number; height: number }> = merge(
this.resize$,
this.#imageWrapperDimensions$
).pipe(filter(dim => dim.width > 0));