DEV Community

loading...
Cover image for Agregar parámetros al navegar en Angular

Agregar parámetros al navegar en Angular

facurodriguez profile image Facundo Rodriguez ・4 min read

Existen ocasiones en donde necesitamos pasar un parámetro, generalmente un identificador, a una ruta con la intención de utilizarlo para llamar a una API y obtener cierta información. En esta ocasión vamos a ver cómo definir una ruta que acepta un parámetro, cómo utilizar la directiva routerLink para pasar el valor del parámetro a través de la ruta y también cómo acceder al valor del parámetro desde un componente.

Crear un nuevo componente

En primer lugar vamos a crear un nuevo componente ejecutando el siguiente comando del Angular CLI:

ng generate component post
Enter fullscreen mode Exit fullscreen mode

Definir la nueva ruta

Lo próximo a realizar es agregar una nueva ruta hacia nuestro nuevo componente en el array de definiciones de rutas dentro de app.module.ts. Vamos a crear un nuevo objeto y esta vez en la propiedad path necesitaremos agregar /:id para indicar que la ruta espera recibir un parámetro llamado id. La definición de las rutas quedará de la siguiente forma:

// src/app/app.module.ts
const routes: Route[] = [
  { path: "home", component: HomeComponent },
  { path: "posts", component: PostsComponent },
  { path: "posts/:id", component: PostComponent },
  { path: "**", redirectTo: "home" }
];
Enter fullscreen mode Exit fullscreen mode

Si ejecutamos el comando ng serve podremos navegar a nuestro nuevo componente modificando la URL de nuestro navegador a, por ejemplo, /posts/1. De esta forma, el valor del parámetro id será el que pasemos al final de la URL.

Enlazar con nuestra aplicación

Para navegar hacia el nuevo componente desde nuestra aplicación haremos uso de la directiva routerLink y agregaremos algunos valores de parámetros para simular un listado de links de navegación dentro de nuestro PostsComponent.

<!-- src/app/posts/posts.component.html -->
<ul>
  <li><a [routerLink]="['/posts', 1]">Post 1</a></li>
  <li><a [routerLink]="['/posts', 2]">Post 2</a></li>
  <li><a [routerLink]="['/posts', 3]">Post 3</a></li>
</ul>
Enter fullscreen mode Exit fullscreen mode

De esta manera le indicamos a Angular que queremos navegar a las rutas /posts/1, /posts/2 o /posts/3 al hacer click en alguno de los links.

Obtener el valor del parámetro

Como hablamos al principio, es posible que querramos obtener cierta información utilizando el valor del parámetro id por lo que vamos a analizar las alternativas que tenemos para lograrlo.

Hay dos maneras diferentes de obtener el valor del parámetro.

La primera es a través del snapshot de la ruta. El snapshot de la ruta nos provee de un objeto llamado paramMap que expone los métodos get, getAll y has para interactuar con los parámetros de la ruta actual.

Para acceder al snapshot de la ruta es necesario inyectar en el componente la clase ActivatedRoute como se muestra a continuación:

// src/app/post/post.component.ts
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";

@Component({
  selector: "app-post",
  templateUrl: "./post.component.html",
  styleUrls: ["./post.component.css"]
})
export class PostComponent implements OnInit {
  id: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.id = this.route.snapshot.paramMap.get("id");
  }
}
Enter fullscreen mode Exit fullscreen mode

Y, para simplificar el ejemplo, vamos a simplemente mostrar el valor en el html:

<!-- src/app/post/post.component.html -->
<p>
  Post con id: {{ id }}
</p>
Enter fullscreen mode Exit fullscreen mode

Haciendo click sobre cada link observaremos que la aplicación muestra correctamente el valor del parámetro. Sin embargo, esta alternativa para obtener el valor del identificador tiene una falencia ya que si la navegación a otros post se produce dentro de nuestro PostCompoent, éste no detecta el cambio en el paramMap por lo que no realiza la navegación.

error-gif

Suscribir a los cambios en paramMap

Para solucionar el inconveniente antes mencionado debemos reemplazar el uso del snapshot de la ruta por una suscipción al parámetro paramMap del ActivatedRoute inyectado. De esta forma estaremos observando los cambios que suceden sobre los parámetros de la ruta y reaccionando correctamente ante cada uno de ellos.

El componente pasaría verse de la siguiente forma:

// src/app/post/post.component.ts
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, ParamMap } from "@angular/router";

@Component({
  selector: "app-post",
  templateUrl: "./post.component.html",
  styleUrls: ["./post.component.css"]
})
export class PostComponent implements OnInit {
  id: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.paramMap.subscribe((params: ParamMap) => {
      this.id = params.get('id');
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Lo más importante a recordar a la hora de decidir entre cuáles de los métodos utilizar es saber en dónde sucede el cambio del parámetro.

Si el valor del parámetro es modificado dentro del mismo componente que lo utiliza entonces debemos suscribirnos al paramMap.

En caso de que este no sea alterado dentro del componente podremos utilizar el snapshot de la ruta sin inconvenientes.

Aquí se puede ver el código final:

Stackblitz

Discussion

pic
Editor guide