Cómo utilizar los solucionadores de rutas con Angular Router

Introducción

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Configuración del proyecto
  • Paso 2: creación de un solucionador
  • Paso 3: Configuración de rutas
  • Paso 4: Acceso a los datos resueltos en el componente
  • Paso 5: Resolución de datos desde una API
  • Paso 6: Acceso a los parámetros de ruta
  • Paso 7: Manejo de errores
  • Conclusión
  • Una forma de gestionar la recuperación y visualización de datos de una API es dirigir a un usuario a un componente y, luego, en ngOnInitel enlace de ese componente, llamar a un método de un servicio para obtener los datos necesarios. Mientras se obtienen los datos, tal vez el componente pueda mostrar un indicador de carga.

    Hay otra forma de utilizar lo que se conoce como route resolver, que permite obtener datos antes de navegar a la nueva ruta.

    Una API que está disponible para su uso es la API de Hacker News . Hacker News es un sitio web para compartir enlaces y debatir sobre ellos. La API se puede utilizar para recuperar las publicaciones más populares y mostrar información sobre publicaciones individuales.

    En este tutorial, implementará un solucionador de ruta que obtiene datos de la API de Hacker News antes de navegar a una ruta que muestra los datos recopilados.

    Prerrequisitos

    Para completar este tutorial, necesitarás:

    • Node.js instalado localmente, lo cual puedes hacer siguiendo Cómo instalar Node.js y crear un entorno de desarrollo local .
    • Algunos conocimientos sobre la configuración de un proyecto Angular .

    Este tutorial fue verificado con Node v15.3.0, npmv6.14.9, @angular/corev11.0.1, @angular/commonv11.0.1, @angular/routerv11.0.1 y rxjsv6.6.0.

    Paso 1: Configuración del proyecto

    Para el propósito de este tutorial, construirás a partir de un proyecto Angular predeterminado generado con @angular/cli.

    1. npx @angular/cli new angular-route-resolvers-example --style=css --routing --skip-tests

    Esto configurará un nuevo proyecto Angular con estilos establecidos en “CSS” (a diferencia de “Sass”, Less” o “Stylus”), enrutamiento habilitado y omisión de pruebas.

    Navegue hasta el directorio del proyecto recién creado:

    1. cd angular-route-resolvers-example

    En este punto, tienes un nuevo proyecto Angular con @angular/router.

    Paso 2: creación de un solucionador

    Comencemos por implementar un solucionador que devuelva una cadena después de un retraso de 2 segundos. Esta pequeña prueba de concepto puede ayudar a explorar los aspectos básicos de las rutas de cableado que se pueden aplicar a proyectos más grandes.

    Primero, crea una clase separada para el solucionador en un archivo propio:

    1. ./node_modules/@angular/cli/bin/ng generate resolver news

    Esto se utilizará @angular/clipara generar un solucionador llamado news:

    src/app/noticias.resolver.ts

    import { Injectable } from '@angular/core';import { Resolve } from '@angular/router';import { Observable, of } from 'rxjs';import { delay } from 'rxjs/operators';@Injectable({  providedIn: 'root'})export class NewsResolver implements ResolveObservablestring {  resolve(): Observablestring {    return of('Route!').pipe(delay(2000));  }}

    Para implementar la interfaz del enrutador Angular, Resolvees necesario que la clase tenga un resolvemétodo. Lo que se devuelva desde ese método serán los datos resueltos.

    Este código devolverá un observable que envuelve una cadena después de un retraso de 2 segundos.

    Paso 3: Configuración de rutas

    Para poder experimentar dos rutas diferentes, necesitarás dos componentes nuevos. homeEsta será la página de inicio y topcontará con las publicaciones más importantes de la API de Hacker News.

    Primero, use @angular/clipara generar un homecomponente:

    1. ./node_modules/@angular/cli/bin/ng generate component home

    Luego, use @angular/clipara generar un topcomponente:

    1. ./node_modules/@angular/cli/bin/ng generate component top

    Ahora puede configurar el módulo de enrutamiento para incluir el solucionador.

    src/app/app-routing.module.ts

    import { NgModule } from '@angular/core';import { Routes, RouterModule } from '@angular/router';import { NewsResolver } from './news.resolver';import { TopComponent } from './top/top.component';import { HomeComponent } from './home/home.component';const routes: Routes = [  {    path: '',    pathMatch: 'full',    component: HomeComponent  },  {    path: 'top',    component: TopComponent,    resolve: { message: NewsResolver }  }];@NgModule({  imports: [RouterModule.forRoot(routes)],  exports: [RouterModule]})export class AppRoutingModule { }

    Observe cómo se proporciona el solucionador como si fuera un servicio y luego se incluye el solucionador con la definición de ruta. Aquí, los datos resueltos estarán disponibles bajo la messageclave.

    Paso 4: Acceso a los datos resueltos en el componente

    En el componente, puede acceder a los datos resueltos utilizando la datapropiedad del objeto ActivatedRoutede snapshot:

    src/app/top/top.component.ts

    import { Component, OnInit } from '@angular/core';import { ActivatedRoute } from '@angular/router';@Component({ ... })export class TopComponent implements OnInit {  data: any;  constructor(private route: ActivatedRoute) {}  ngOnInit(): void {    this.data = this.route.snapshot.data;  }}

    Ahora, en el componente, puedes acceder al Route!mensaje de la siguiente manera:

    src/app/top/top.modulo.html

    pThe message: {{ data.message }}/p

    En este punto, puedes compilar tu aplicación:

    1. npm start

    Y visitar localhost:4200/topen un navegador web.

    OutputThe message: Route!

    Observarás al navegar hacia la topruta que ahora hay un retraso de 2 segundos porque los datos se resuelven primero.

    Paso 5: Resolución de datos desde una API

    Hagamos que las cosas sean más reales obteniendo datos de una API. Aquí crearás un servicio que obtenga datos de la API de Hacker News.

    Necesitará HttpClient para solicitar el punto final.

    Primero, agrega el HttpClientModulea app.module.ts:

    src/app/app.module.ts

    import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { HttpClientModule } from '@angular/common/http';import { AppRoutingModule } from './app-routing.module';import { AppComponent } from './app.component';@NgModule({  declarations: [    AppComponent  ],  imports: [    BrowserModule,    HttpClientModule,    AppRoutingModule  ],  providers: [],  bootstrap: [AppComponent]})export class AppModule { }

    Luego, crea un nuevo servicio:

    1. ./node_modules/@angular/cli/bin/ng generate service news

    Esto se utilizará @angular/clipara generar un servicio llamado news:

    src/app/noticias.servicio.ts

    import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';@Injectable({  providedIn: 'root'})export class NewsService {  constructor(private http: HttpClient) { }  getTopPosts() {    const endpoint = 'https://hacker-news.firebaseio.com/v0/topstories.json';    return this.http.get(endpoint);  }}

    Y ahora puedes reemplazar el código de cadena NewsResolvercon NewsService:

    src/app/noticias.resolver.ts

    import { Injectable } from '@angular/core';import { Resolve } from '@angular/router';import { Observable } from 'rxjs';import { NewsService } from './news.service';export class NewsResolver implements Resolveany {  constructor(private newsService: NewsService) {}  resolve(): Observableany {    return this.newsService.getTopPosts();  }}

    En este punto, si miras la topruta en un navegador, se te presentará una lista de números que representan idalgunas de las publicaciones principales en Hacker News.

    Paso 6: Acceso a los parámetros de ruta

    Puede obtener acceso a los parámetros de ruta actuales en su resolver usando el ActivatedRouteSnapshotobjeto.

    A continuación se muestra un ejemplo en el que utilizaría un resolver para obtener acceso al idparámetro de la ruta actual.

    Primero, use el @angular/clipara generar un resolver llamado post:

    1. ./node_modules/@angular/cli/bin/ng generate resolver news

    Luego, modifíquelo post.resolver.tspara utilizar ActivatedRouteSnapshot:

    fuente/aplicación/post.resolver.ts

    import { Injectable } from '@angular/core';import { Resolve, ActivatedRouteSnapshot } from '@angular/router';import { Observable } from 'rxjs';import { NewsService } from './news.service';@Injectable({  providedIn: 'root'})export class PostResolver implements Resolveany {  constructor(private newsService: NewsService) {}  resolve(route: ActivatedRouteSnapshot): Observableany {    return this.newsService.getPost(route.paramMap.get('id'));  }}

    A continuación, agregue un getPostmétodo a NewsService:

    src/app/noticias.servicio.ts

    // ...export class NewsService {  constructor(private http: HttpClient) { }  // ...  getPost(postId: string) {    const endpoint = 'https://hacker-news.firebaseio.com/v0/item';    return this.http.get(`${endpoint}/${postId}.json`);  }}

    Y agregamos PostResolvery la post/:idruta a app-routing.module.ts:

    src/app/app-routing.module.ts

    // ...import { PostResolver } from './post.resolver';// ...const routes: Routes = [  // ...  {    path: 'post/:id',    component: PostComponent,    resolve: { newsData: PostResolver }  }];// ...

    A continuación, crea el nuevo PostComponent:

    1. ./node_modules/@angular/cli/bin/ng generate component post

    Luego, modifique post.component.tspara utilizar datos de instantáneas:

    src/app/post/post.component.ts

    import { Component, OnInit } from '@angular/core';import { ActivatedRoute } from '@angular/router';@Component({ ... })export class PostComponent implements OnInit {  data: any;  constructor(private route: ActivatedRoute) { }  ngOnInit(): void {    this.data = this.route.snapshot.data;  }}

    Y modificar post.component.htmlpara mostrar el title:

    src/aplicación/publicación/publicación.componente.html

    p{{ data.newsData.title }}/p

    Ahora, si un usuario accede a , se resolverán http://localhost:4200/post/15392112los datos del ID de la publicación .15392112

    Paso 7: Manejo de errores

    En caso de que se produzca un error al obtener los datos, puede detectarlo y solucionarlo en el solucionador utilizando el operador catch de RxJS . Por ejemplo, algo como esto:

    src/app/noticias.resolver.ts

    import { Injectable } from '@angular/core';import { Resolve } from '@angular/router';import { Observable, of } from 'rxjs';import { catchError } from 'rxjs/operators';import { NewsService } from './news.service';@Injectable()export class NewsResolver implements Resolveany {  constructor(private newsService: NewsService) {}  resolve(): Observableany {    return this.newsService.getTopPosts().pipe(catchError(() = {      return of('data not available at this time');    }));  }}

    O podría devolver un EMPTYobservable y devolver al usuario a la ruta raíz:

    src/app/noticias.resolver.ts

    import { Injectable } from '@angular/core';import { Router, Resolve } from '@angular/router';import { Observable, EMPTY } from 'rxjs';import { catchError } from 'rxjs/operators';import { NewsService } from './news.service';@Injectable()export class NewsResolver implements Resolveany {  constructor(private router: Router, private newsService: NewsService) {}  resolve(): Observableany {    return this.newsService.getTopPosts().pipe(catchError(() = {      this.router.navigate(['/']);      return EMPTY;    }));  }}

    Estos dos enfoques conducirán a una mejor experiencia de usuario si hay un error al recuperar datos de la API.

    Conclusión

    En este tutorial, implementó un solucionador de ruta que obtiene datos de la API de Hacker News antes de navegar a una ruta que muestra los datos recopilados. Esto se logró utilizando @angular/router, @angular/common/httpy rxjs.

    Si desea obtener más información sobre Angular, consulte nuestra página de temas de Angular para ver ejercicios y proyectos de programación.

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion