Skip to content

Commit

Permalink
fix: preserve slides that have already been fetched
Browse files Browse the repository at this point in the history
  • Loading branch information
dhhyi committed May 20, 2022
1 parent 74b99d1 commit a21bc45
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 26 deletions.
Expand Up @@ -6,7 +6,7 @@ <h2>{{ productLinkTitle }}</h2>
<swiper [config]="swiperConfig">
<ng-template *ngFor="let sku$ of productSKUs" swiperSlide let-data>
<ish-product-item
*ngIf="data.isVisible && sku$ | async as sku"
*ngIf="lazyFetch(data.isVisible, sku$) | async as sku"
ishProductContext
[sku]="sku"
></ish-product-item>
Expand Down
@@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, Inject, Input } from '@angular/core';
import { RxState } from '@rx-angular/state';
import { Observable, combineLatest, of } from 'rxjs';
import { EMPTY, Observable, combineLatest, of } from 'rxjs';
import { filter, map, tap } from 'rxjs/operators';
import SwiperCore, { Navigation, Pagination, SwiperOptions } from 'swiper';

Expand Down Expand Up @@ -47,6 +47,11 @@ export class ProductLinksCarouselComponent {

productSKUs$ = this.state.select('products$');

/**
* track already fetched SKUs
*/
private fetchedSKUs = new Set<Observable<string>>();

/**
* configuration of swiper carousel
* https://swiperjs.com/swiper-api
Expand Down Expand Up @@ -92,35 +97,43 @@ export class ProductLinksCarouselComponent {
},
};

this.state.connect(
'products$',
combineLatest([
this.state.select('products'),
this.state.select('displayOnlyAvailableProducts'),
this.state.select('hiddenSlides'),
]).pipe(
map(([products, displayOnlyAvailableProducts, hiddenSlides]) => {
const filteredProducts$ = combineLatest([
combineLatest([this.state.select('products'), this.state.select('displayOnlyAvailableProducts')]).pipe(
map(([products, displayOnlyAvailableProducts]) => {
// prepare lazy observables for all products
if (displayOnlyAvailableProducts) {
return products
.map((sku, index) =>
this.shoppingFacade.product$(sku, ProductCompletenessLevel.List).pipe(
tap(product => {
if (!product.available || product.failed) {
this.state.set('hiddenSlides', () =>
[...this.state.get('hiddenSlides'), index].filter((v, i, a) => a.indexOf(v) === i)
);
}
}),
filter(product => product.available && !product.failed),
mapToProperty('sku')
)
return products.map((sku, index) =>
this.shoppingFacade.product$(sku, ProductCompletenessLevel.List).pipe(
tap(product => {
// add slide to the hidden list if product is not available
if (!product.available || product.failed) {
this.state.set('hiddenSlides', () =>
[...this.state.get('hiddenSlides'), index].filter((v, i, a) => a.indexOf(v) === i)
);
}
}),
filter(product => product.available && !product.failed),
mapToProperty('sku')
)
.filter((_, index) => !hiddenSlides.includes(index));
);
} else {
return products.map(sku => of(sku));
}
})
)
);
),
this.state.select('hiddenSlides'),
]).pipe(map(([products, hiddenSlides]) => products.filter((_, index) => !hiddenSlides.includes(index))));

this.state.connect('products$', filteredProducts$);
}

lazyFetch(fetch: boolean, sku$: Observable<string>): Observable<string> {
if (fetch) {
this.fetchedSKUs.add(sku$);
}
if (this.fetchedSKUs.has(sku$)) {
return sku$;
}
return EMPTY;
}
}

1 comment on commit a21bc45

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Azure Demo Servers are available:

Please sign in to comment.