From 354be9d09f4c50a6c9c7c896ed0e6d11006f481c Mon Sep 17 00:00:00 2001 From: sanderelias Date: Wed, 18 Nov 2020 14:17:23 +0100 Subject: [PATCH 1/2] small refactor --- src/app/services/hero.service.ts | 57 ++++++++++++++------------------ 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/app/services/hero.service.ts b/src/app/services/hero.service.ts index dce746f..5820d36 100644 --- a/src/app/services/hero.service.ts +++ b/src/app/services/hero.service.ts @@ -1,13 +1,12 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs'; +import { BehaviorSubject, combineLatest, of } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, + mergeMap, pluck, - scan, - share, switchMap, tap, } from 'rxjs/operators'; @@ -55,6 +54,7 @@ const DEFAULT_STATE = { search: '', page: 0, limit: LIMIT_MID, + heroCache: {}, }; @Injectable({ @@ -69,44 +69,37 @@ export class HeroService { userPage$ = this.page$.pipe(map(page => page + 1)); limit$ = this.heroState.pipe(pluck('limit')); - changes$ = combineLatest([ - this.search$.pipe(map(search => search.trim())), - this.page$, - this.limit$, - ]).pipe(map(([search, page, limit]) => ({ search, page, limit }))); - - heroesResponse$ = this.changes$.pipe( + heroesResponse$ = this.search$.pipe( debounceTime(500), - distinctUntilChanged( - (prev, curr) => JSON.stringify(prev) === JSON.stringify(curr), - ), - scan((acc, curr) => { - if (!acc[JSON.stringify(curr)]) { - acc[JSON.stringify(curr)] = { response: null, state: curr }; - } - acc['THEVERYLATEST'] = acc[JSON.stringify(curr)]; - return acc; - }, {}), - switchMap((acc: any) => { - const latest = acc.THEVERYLATEST; - const state = latest.state; - if (latest.response != null) { - return of(latest.response); + distinctUntilChanged(), + mergeMap(() => this.heroState), + switchMap(state => { + const search = state.search.trim(); + if (state.heroCache[search]) { + return of(state.heroCache[search]); } const params: any = { apikey: environment.MARVEL_API.PUBLIC_KEY, limit: `${state.limit}`, offset: `${state.page * state.limit}`, // page * limit }; - if (state.search && state.search.length) { - params.nameStartsWith = state.search; + if (search && search.length) { + params.nameStartsWith = search; } - return this.http - .get(HERO_API, { params }) - .pipe(tap(res => (latest.response = res))); + return this.http.get(HERO_API, { params }).pipe( + tap(res => { + /** merge in new result */ + const heroCache = { + ...state.heroCache, + [search]: res, + }; + /** update the local state. */ + this.heroState.next({ ...state, heroCache }); + }), + ); }), - share(), ); + heroes$ = this.heroesResponse$.pipe(map((res: any) => res.data.results)); total$ = this.heroesResponse$.pipe(map((res: any) => res.data.total)); totalPages$ = combineLatest([this.total$, this.limit$]).pipe( @@ -136,7 +129,7 @@ export class HeroService { const state = this.heroState.getValue(); this.heroState.next({ ...state, - search, + search: search.trim(), page: 0, }); } From f9591cb8148d18c89bd817f24468c14e2fa57960 Mon Sep 17 00:00:00 2001 From: sanderelias Date: Wed, 18 Nov 2020 14:24:56 +0100 Subject: [PATCH 2/2] remove now unneeded local const --- src/app/services/hero.service.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/app/services/hero.service.ts b/src/app/services/hero.service.ts index 5820d36..52c1273 100644 --- a/src/app/services/hero.service.ts +++ b/src/app/services/hero.service.ts @@ -74,24 +74,23 @@ export class HeroService { distinctUntilChanged(), mergeMap(() => this.heroState), switchMap(state => { - const search = state.search.trim(); - if (state.heroCache[search]) { - return of(state.heroCache[search]); + if (state.heroCache[state.search]) { + return of(state.heroCache[state.search]); } const params: any = { apikey: environment.MARVEL_API.PUBLIC_KEY, limit: `${state.limit}`, offset: `${state.page * state.limit}`, // page * limit }; - if (search && search.length) { - params.nameStartsWith = search; + if (state.search && state.search.length) { + params.nameStartsWith = state.search; } return this.http.get(HERO_API, { params }).pipe( tap(res => { /** merge in new result */ const heroCache = { ...state.heroCache, - [search]: res, + [state.search]: res, }; /** update the local state. */ this.heroState.next({ ...state, heroCache });