Understanding Angular Route Resolvers

winding-road-between-forest

Het ontwikkelen van een echte applicatie met meerdere aanroepen naar de server kan vol zitten met bugs. Als je hier bent, betekent dit dat je hebt geworsteld met de vertraging van API-aanroepen. Deze vertragingen kunnen een negatieve UX veroorzaken. Vandaag gaan we Route Resolvers in Angular 8 begrijpen. Er zijn verschillende dingen die we kunnen doen om de gebruikerservaring te verbeteren, zoals het weergeven van een voortgangsindicator. Om bij het onderwerp te blijven, laten we eens kijken wat een Route Resolver is en wat we ermee kunnen bereiken.

What Is an Angular Route Resolver?

Een Resolver is een klasse die de Resolve interface van Angular Router implementeert. In feite, Resolver is een service die moet worden in de root-module. In principe fungeert een Resolver als middleware, die kan worden uitgevoerd voordat een component wordt geladen.

You may also like: Angular Resolvers.

Waarom Route Resolvers gebruiken in Angular?

Om uit te leggen hoe een resolver kan worden gebruikt in Angular, laten we eens denken aan het scenario wanneer u *ngIf="some condition" gebruikt, en uw logica is afhankelijk van de lengte van een array, die wordt gemanipuleerd wanneer een API-aanroep is voltooid. U wilt bijvoorbeeld in een component de items van deze array weergeven die zojuist zijn opgehaald in een ongeordende lijst.

<ul><li *ngFor="let item of items">{{item.description}}</li></ul>

In deze situatie kunt u in een probleem terechtkomen omdat uw gegevens pas naar boven komen nadat de component klaar is. Items in de array bestaan nog niet echt. Hier komt de Route Resolver van pas. Angular’s Route Resolver klasse zal je data ophalen voordat de component klaar is. Je conditionele statements zullen soepel werken met de Resolver.

Resolve Interface

Voordat we beginnen met het implementeren van een route resolver, laten we eerst eens kijken hoe de Resolve interface eruit ziet.

export interface Resolve<T> { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T { return 'Data resolved here...' }}

Als je een Route Resolver wilt maken, moet je een nieuwe klasse maken die de bovenstaande interface zal implementeren. Deze interface voorziet ons van een resolve functie, die je twee parameters geeft voor het geval je ze nodig hebt. De eerste is de route, die van het type ActivatedRouteSnapshot is, en de tweede is de status, van het type RouterStateSnapshot. Hier kunt u een API-oproep doen die de gegevens krijgt die u nodig hebt voordat uw component wordt geladen.

Via de route-parameter kunt u route-parameters krijgen die in de API-oproep kunnen worden gebruikt. De resolve-methode kan een Observable, een belofte of alleen een aangepast type teruggeven.

Note: Het is belangrijk te vermelden dat alleen opgeloste gegevens via deze methode zullen worden teruggegeven.

Dit is een fout die veel mensen zullen maken als ze resolvers voor de eerste keer gebruiken! Je moet ze dus afmaken voordat je ze de router instuurt.

Gegevens naar de router sturen via een Resolver

Laat me je tonen wat ik bedoel in de bovenstaande sectie. Laten we zeggen dat je een methode hebt die een observeerbare retourneert:

items: any = ;getData(): Observable<any> { const observable = Observable.create(observer => { observer.next(this.items) }); return observable;}

Nu zul je zien dat het abonnement dat we hebben, nooit aanslaat. Dit komt omdat u de gegevens niet correct verstuurt. U maakt het abonnement niet af. Om die fout te verhelpen, moet je het abonnement voltooien door nog een regel code toe te voegen.

observer.complete();

In het geval dat je een belofte terugstuurt, moet je die oplossen voordat je de gegevens naar de router stuurt.

Een route-resolver implementeren

Nadat we klaar zijn met de basisuitleg en waarom en hoe je een route-resolver gebruikt, laten we beginnen er een te implementeren. In dit korte voorbeeld ga ik er van uit dat je bekend bent met Angular’s CLI commando’s en hoe je een nieuw project aanmaakt, dus ik zal alleen de verplichte code demonstreren. Je kunt het demo project vinden via de GitHub repository aan het eind van het artikel.

In dit voorbeeld zal ik jsonplaceholder gebruiken als een nep API om gebruikersgegevens op te halen om API calls met route resolvers te demonstreren.

Op de eerste plaats hebben we een service nodig die de gebruikersgegevens voor ons ophaalt. In deze service hebben we een functie genaamd getUsers() die een observeerbare retourneert.

@Injectable({providedIn: 'root'})export class FakeApiService { constructor(private http: HttpClient) { } private usersEndpoint = "https://jsonplaceholder.typicode.com/users"; getUsers(): Observable<any> { // We do not subscribe here! We let the resolver take care of that... return this.http.get(this.usersEndpoint); }}

Het is belangrijk dat je je niet abonneert op de functie getUsers. De route resolver genaamd UserResolver zal dit voor je regelen. De volgende stap is het maken van een nieuwe service met de naam UserResolver, die de resolve-functie van de Resolve-interface van de router zal implementeren.

@Injectable({providedIn: 'root'})export class UserResolverService implements Resolve<any> { constructor(private fakeApi: FakeApiService) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { return this.fakeApi.getUsers().pipe( catchError((error) => { return empty(); }); ); }}

Deze service, UserResolver, zal zich automatisch abonneren op de getUsers-observable en de router voorzien van de opgehaalde gegevens. In geval van een fout tijdens het ophalen van de gegevens, kunt u een lege observeerbare sturen en de router zal niet verder gaan met de route.

De navigatie wordt op dit punt beëindigd. Deze laatste stap is om een component te maken die aangeroepen wordt als de gebruiker naar de /users route gaat. Typisch, zonder een Resolver, zult u de gegevens moeten ophalen op de ngOnInit haak van de component en de fouten moeten behandelen die worden veroorzaakt door ‘geen gegevens’ bestaat. De gebruikerscomponent is een eenvoudige. Het haalt alleen de gegevens van de gebruiker uit de ActivatedRoute en geeft ze weer in een ongeordende lijst.

Nadat je de user’s component hebt gemaakt, moet je de routes definiëren en de router vertellen dat hij een resolver moet gebruiken ( UserResolver). Dit kan worden bereikt met de volgende code in de app-routing.modulte.ts.

const routes: Routes = ;@NgModule({ imports: , exports: })export class AppRoutingModule { }

U moet de eigenschap resolve instellen in de route van de gebruiker en de UserResolver declareren. De gegevens zullen worden doorgegeven aan een object met een eigenschap genaamd users. Daarna ben je bijna klaar. Er is nog maar één ding dat je moet doen. U moet de opgehaalde gegevens in de gebruikerscomponent krijgen via de ActivatedRoute met de volgende code.

constructor(private activatedRoute: ActivatedRoute) { }users: any;ngOnInit() { this.activatedRoute.data.subscribe((data: { users: any }) => { this.users = data.users; });}

Dan kunt u ze gewoon in HTML weergeven zonder *ngIf statements ( *ngIf="users && users.length > 0 ) omdat de gegevens er al zullen zijn voordat de component wordt geladen.

<h2>Fetched Users:</h2><ul><li *ngFor="let user of users">{{ user.name }}</li></ul>

Samenvatting

Ter afsluiting van dit artikel over Route Resolvers, wil ik nogmaals wijzen op de voordelen die ze ons bieden. Ten eerste vermijden we de vervelende controles die op HTML-niveau moeten worden uitgevoerd, zodat we geen problemen hebben totdat onze gegevens zijn ontvangen. Ten tweede stellen ze ons in staat ons meer te concentreren op de gebruikerservaring, omdat we kunnen stoppen met navigeren als er een gegevensfout optreedt tijdens het ophalen, zonder dat we de preview-component hoeven te laden. We kunnen ook meer doen voordat we de navigatie voltooien, zoals meer logica aankoppelen of de gegevens in kaart brengen voordat we de geladen component openen.

De demo code is beschikbaar op GitHub.

Verder lezen

  • Angular Tutorial: Angular 7 en het RESTEasy Framework.
  • Een Angular 5 applicatie stap voor stap bouwen.
  • Angular 7 + Spring Boot Applicatie: Hello World Voorbeeld.

Plaats een reactie