buscando_pelo_parametro - VWJavascript/Alurapic GitHub Wiki

Buscando pelo parâmetro

Podemos ter acesso aos parâmetros da rota através do serviço ActivatedRoute. Que tal berrarmos para o framework solicitando esse serviço? Vamos fazer importar ActivatedRoute e indicá-lo como dependência em nossa classe CadastroComponent, fazendo com que o sistema de injeção de dependências do Angular injete-o para nós. Inclusive vamos adicionar a propriedade mensagem assim como fizemos em CadastroComponent para exibirmos notificações para o usuário:

// alurapic/client/app/cadastro/cadastro.component.ts

import { Component, Input } from '@angular/core';
import { FotoComponent } from '../foto/foto.component';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FotoService } from '../foto/foto.service';
import { ActivatedRoute } from '@angular/router';

@Component({
    moduleId: module.id,
    selector: 'cadastro',
    templateUrl: './cadastro.component.html' 
})
export class CadastroComponent { 

    foto: FotoComponent = new FotoComponent();
    service: FotoService;
    meuForm: FormGroup;
    route: ActivatedRoute; // nova propriedade
    mensagem: string = ''; // nova propriedade

    constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute) {

        this.route = route;

        // código posterior omitido

Vamos adicionar também aquela mensagem condicional, igualzinho ao que fizemos no template de ListagemComponent:

<!-- alurapic/client/app/cadastro/cadastro.component.html -->

<div class="container">
    <h1 class="text-center">{{foto.titulo}}</h1>
    <p *ngIf="mensagem.length" class="alert alert-info">{{mensagem}}</p>

<!-- código posterior omitido -->

Através da instância de ActivatedRoute obtermos o parâmetro passado da seguinte maneira:

import { Component, Input } from '@angular/core';
import { FotoComponent } from '../foto/foto.component';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FotoService } from '../foto/foto.service';
import { ActivatedRoute } from '@angular/router';

@Component({
    moduleId: module.id,
    selector: 'cadastro',
    templateUrl: './cadastro.component.html' 
})
export class CadastroComponent { 

    foto: FotoComponent = new FotoComponent();
    service: FotoService;
    meuForm: FormGroup;
    route: ActivatedRoute;
    mensagem: string = '';

    constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute) {

        this.route = route;
        this.service = service;

        this.route.params.subscribe(params => console.log(params['id']));

        // código posterior omitido

Vamos digitar no browser a URL localhost:3000/cadastro/10. Um olhar atento no console mostra que o ID que passamos como parâmetro para a URL é exibido. Perfeito, mas precisamos alterar o nosso routerLink que utilizamos na tag que envolve nossa foto. A ideia é que ao ser clicado, ele construa o endereço para nós levando em consideração o ID da foto:

<!-- alurapic/client/app/listagem/listagem.component.html -->

<div class="row">
    <painel *ngFor="let foto of fotos | filtroPorTitulo: textoProcurado.value" titulo="{{foto.titulo | uppercase}}"  class="col-md-2">

        <a [routerLink]="['/cadastro', foto._id]">

            <foto titulo="{{foto.titulo}}" url="{{foto.url}}"></foto>
        </a>

        <button class="btn btn-danger btn-block" (click)="remove(foto)">Remover</button>
    </painel>
</div><!-- fim row -->

Agora, para cada foto clicada, seremos levados para CadastroComponent e este terá acesso ao ID da foto que clicamos. Precisamos agora buscar a foto no servidor.

Só podemos buscar a foto apenas se Cadastro recebeu o ID de alguma foto, claro. O código é muito parecido com o que já fizemos.

// alurapic/client/app/cadastro/cadastro.component.ts

import { Component, Input } from '@angular/core';
import { FotoComponent } from '../foto/foto.component';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FotoService } from '../foto/foto.service';
import { ActivatedRoute } from '@angular/router';

@Component({
    moduleId: module.id,
    selector: 'cadastro',
    templateUrl: './cadastro.component.html' 
})
export class CadastroComponent { 

    foto: FotoComponent = new FotoComponent();
    service: FotoService;
    meuForm: FormGroup;
    route: ActivatedRoute;
    mensagem: string = '';

    constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute) {

        this.route = route;
        this.service = service;

        this.route.params.subscribe(params => {

            let id = params['id'];

            if(id) {

                this.service.buscaPorId(id)
                    .subscribe(
                        foto => this.foto = foto,
                        erro => console.log(erro));    
            }            
         });

         // código posterior omitido

Nosso código não compila porque o método buscaPorId ainda não existe em FotoService. Vamos criá-lo:

// código anterior omitido

// alurapic/client/app/foto/foto.service.ts 


buscaPorId(id: string): Observable<FotoComponent> {

    return this.http
        .get(this.url + '/' + id)
        .map(res => res.json());
}

// código posterior omitido

Pronto. Para cada foto que acessarmos em ListagemComponent, seus dados são exibidos em CadastroComponent. No entanto, podemos melhorar a legibilidade do nosso código. Para não deixar um monte de código perdido dentro do nosso construtor, vamos criar um método com um nome que deixa bem claro o que o código faz. Vamos chamá-lo de buscaPorId e fazer com que ele receba o ID da foto que desejamos buscar.

⚠️ **GitHub.com Fallback** ⚠️