jueves, 19 de abril de 2018

Resolvers en Angular

Un resolver es un código que se ejecuta después de hacer clic en un enlace, y antes de que se haya cargado el componente asociado a dicho enlace.

Básicamente el flujo que realizamos al usar un resolver es:

- Hacemos clic en un enlace que habremos definido en un router module.
- Se ejecuta el código asociado al resolver. El resolver puede devolver un valor (que puede ser un observable o cualquier otro tipo) al componente asociado al enlace sobre el que hemos hecho clic.
- Cargamos el componente pudiendo usar los datos obtenidos del resolver.

Vamos a ver un ejemplo donde mostraremos una serie de enlaces. Cada enlace va a representar un usuario. Al hacer clic en un usuario, pasaremos en la ruta el id asociado al mismo, y antes de cargar el componente asociado, haciendo uso de un resolver vamos a hacer una petición get a un api para traernos la información del usuario, de tal manera que cuando la página esté cargada la información se va a encontrar disponible.

En primer lugar vamos a crear un servicio que implemente la interface genérica resolve<T>.
Esta interface tiene el método resolver() que tenemos que sobreescribir.

En nuestro ejemplo, el método va a recibir un párametro de tipo ActivatedRouteSnapshot que vamos a usar para recuperar los parámetros de la ruta (vamos a tener rutas del estilo users/1, users/2, etc.)

const userId = route.params['id'];

Una vez que obtenemos el id del usuario, llamaremos al api de jsonplaceholder estableciendo una url del siguiente estilo https://jsonplaceholder.typicode.com/users/1




El componente donde vamos a mostrar la información del usuario se llamará user.component.ts
Esta información la va a recibir el componente una vez que el usuario haga clic en el enlace del menú asociado al mismo, y será entoces cuando se llame al resolver que se encargará de recibir el parametro del usuario y realizar la petición httpGet como veremos más adelante.

En el OnInit del componente lo que hacemos es recuperar la información de la llamada que hemos realizado al Api de jsonplaceholder. Esta información la tenemos en el objeto de la clase ActivatedRoute que inyectamos en el contructor, en concreto dentro de la propiedad "data".



En las rutas de nuestra aplicación, que las vamos a definir en el módulo principal será donde indiquemos los resolver que queremos asignar a cada una de ellas. Al inicio de la entrada comentamos que "un resolver es un código que se ejecuta después de hacer click en un enlace, y antes de que se haya cargado el componente asociado a dicho enlace"... y el objetivo que queremos es que cuando hagamos clic en el usuario-1 se cargue la información del usuario-2, con el usuario 2 la información del 2, etc.  por lo que las rutas asociada al componente UserComponent (users/:id) vamos a resolverlas con el UserResolverService

const ROUTES: Routes = [
  { path: '', component: AppComponent },
  { path: 'home', component: AppComponent },
  {
    path: 'users/:id',
    component: UserComponent,
    resolve: {
      user: UserResolverService
    }

  }
];


 Como podemos observar  en el código anterior, las rutas de "users" se resuelven con el servicio que hemos creado anteriormente, el que se encarga de realizar una petición http y dejar los resutados en "user"

En la siguiente imagen vemos el resultado que se muestra en el navegador:


A modo de resumen, hemos creado un servicio que implementa la interfece Resolve, sobreescribiendo el método resolve() de la misma.
Este método se encarga de obtener el parámetro de la ruta sobre la que hemos hecho clic, y devuelve un observable resultado de una petición http al api especificado.
Hemos definido las rutas, especificando para las rutas de usuario un resolve que está asociado al servicio creado inicialmente, y finalmente en el componente hemos pintado en el template los datos que hemos recuperado antes de que se cargara el mismo.

El código fuente completo de este ejemplo se encuentra en
https://github.com/jorgetrigueros/angular-resolver-demo


1 comentario: