Router de Angular: Route Resolvers

Una forma de lidiar con la obtención y visualización de datos de una API es enrutar a un usuario a un componente, y luego en el hook ngOnInit de ese componente llamar a un método en un servicio para obtener los datos necesarios. Mientras se obtienen los datos, quizás el componente pueda mostrar un indicador de carga. Sin embargo, hay otra forma de utilizar lo que se conoce como un resolvedor de rutas, que permite obtener los datos antes de navegar a la nueva ruta.

Simple Resolver

En este post implementaremos un sencillo resolvedor de rutas que obtiene los datos de la API de Hacker News puesta a disposición del proyecto HNPWA antes de navegar a una ruta que muestre los datos recogidos. Empezaremos implementando el resolver más simple que simplemente devuelve una cadena después de un retraso de 2 segundos. Esto debería ayudar a obtener la imagen general de cómo conectar todo.

Crearemos una clase separada para nuestro resolver en un archivo propio:

hn.resolver.ts

Como puedes ver, el único requisito para implementar la interfaz Resolve del router de Angular es que nuestra clase tenga un método resolve. Lo que se devuelva de ese método serán los datos resueltos.

Aquí devolvemos un observable que envuelve una cadena tras un retardo de 2 segundos.

Configuración de la ruta

Ahora podemos configurar nuestro módulo de enrutamiento para que incluya nuestro resolver:

app-routing.module.ts

Nota cómo nuestro resolver se proporciona igual que un servicio y luego incluimos el resolver con nuestra definición de ruta. Aquí los datos resueltos estarán disponibles bajo la clave del mensaje.

Acceso a los datos resueltos en el componente

En el componente, podemos acceder a los datos resueltos utilizando la propiedad data del objeto snapshot de ActivatedRoute:

Y eso es todo lo que necesitamos. Ahora, en nuestro componente, podemos acceder a nuestro mensaje Hello Alligator! de la siguiente manera:

<p>the message: {{ data.message }}</p>

Notarás al navegar a la ruta que ahora hay un retraso de 2 segundos porque los datos se resuelven primero.

Resolviendo datos de una API

Ahora vamos a hacer las cosas más reales obteniendo algunos datos de una API. Aquí crearemos un servicio que obtiene datos de la API de Hacker News.

Aquí está nuestro servicio simple, donde también usamos el nuevo HttpClient:

hn.service.ts

Y ahora podemos cambiar nuestro resolver por algo así:

hn.resolver.ts

Acceso a los parámetros de la ruta

Podemos acceder a los parámetros de la ruta actual en nuestro resolver utilizando el objeto ActivatedRouteSnapshot. Aquí hay un ejemplo en el que usaríamos nuestro resolver para obtener acceso al parámetro id de la ruta actual:

hn.resolver.ts

Nuestra ruta puede tener este aspecto:

{ path: 'post/:id', component: PostComponent, resolve: { hnData: HnResolver }}

Y aquí está el método getPost en nuestro servicio:

getPost(postId: string) { const endpoint = 'https://hnpwa.com/api/v0/item'; return this.http.get(`${endpoint}/${postId}.json`);}

Ahora si un usuario va a, digamos, http://localhost:4200/post/15392112, se resolverán los datos para el id de post 15392112.

Manejo de errores

En caso de que haya un error mientras se obtienen los datos, podrías atrapar y tratar el error en el resolver usando el operador catch de RxJS. Algo así, por ejemplo:

O podrías devolver un observable vacío, en cuyo caso el usuario no será enviado a la nueva ruta:

resolve() { return this.hnService.getTopPosts().catch(() => { return Observable.empty(); });}

Leave a Reply