servico_de_remocao - VWJavascript/Alurapic GitHub Wiki

Serviço de remoção

Excelente, agora que já temos a foto em nosso método podemos solicar ao nosso servidor que a remova para nós. A boa notícia é que já temos uma instância de FotoService em nosso componente Principal, contudo ele ainda não possui um método específico para solicitar ao nosso servidor a remoção de fotos.

Vamos alterar alurapic/client/app/foto/foto.service.js e implementar o método remove:

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

import { Http, Headers, Response } from '@angular/http';
import { FotoComponent } from './foto.component';
import { Observable } from 'rxjs'; 
import { Injectable } from '@angular/core';

@Injectable() 
export class FotoService {

    // código anterior omitido 

    remove(foto: FotoComponent): Observable<Response> {

        return this.http.delete(this.url);
    }    
}

Usamos o http.delete que utiliza por baixo dos panos o verbo DELETE. Veja que também passamos a this.url como parâmetro, a URL que aponta para nosso recurso de fotos no servidor. Contudo temos um problema. Em nenhum momento estamos indicando nessa URL a foto que desejamos que o servidor apague para nós. Faremos indicação completando a URL com o ID da foto que desejamos remover. A razão disso é que nosso servidor está pronto para lidar com requisições do tipo DELETE com essa estrutura:

v1/fotos/3
v1/fotos/15

Quando o verbo DELETE é empregado, nosso servidor entende que tudo que vem depois de v1/fotos/ é o ID da foto que ele deve remover. Sendo assim, precisamos concatenar o ID da foto que recebemos em nosso método com a URL do nosso recurso:

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

// código anterior omitido

remove(foto: FotoComponent): Observable<Response> {

    return this.http.delete(this.url + '/' + foto._id);
}
// código posterior omitido

Como tipamos o parâmetro foto com o tipo FotoComponent, só teremos acesso à _id se ela for uma propriedade de FotoComponent. Toda foto trazida do servidor vem com esse ID gerado automaticamente pelo servidor. Vamos alterar alurapic/client/app/foto/foto.component.ts para adicionarmos a propriedade _id:

import { Component, Input } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'foto', 
    templateUrl: './foto.component.html',
    styleUrls: ['./foto.component.css']
})
export class FotoComponent { 

    @Input() titulo: string;
    @Input() url: string;
    descricao: string;
    _id: string;
}

Agora que já temos o método implementado, vamos voltar para nosso componente ListagemComponent e concluir o método remove. Só não podemos nos esquecer de guardar o serviço injetado em uma propriedade da classe para que possamos utilizá-la em remove.

// alurapic/client/app/listagem/listagem.component.ts

import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { FotoService } from '../foto/foto.service';
import { FotoComponent } from '../foto/foto.component';

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

    fotos: FotoComponent[] = [];
    service: FotoService;

    constructor(service: FotoService) {
        this.service = service;
        this.service.lista()
            .subscribe(
                fotos => this.fotos = fotos,
                erro => console.log(erro)
            );
    }

    remove(foto: FotoComponent): void {

        this.service.remove(foto)
             .subscribe(
                fotos => console.log('foto removida com sucesso'),
                erro => console.log(erro));
    }
}

Remove mais não remove?

Com nosso código em TypeScript compilado sem erros e com o servidor rodando vamos realizar um novo teste. Uma coisa estranha acontece: quando clicamos botão a foto não é removida, mas se forçamos o recarregamento da página a foto que acabamos de remover não aparece. Curioso.

O problema é que estamos removendo corretamente a foto do servidor, mas não estamos atualizando a lista de fotos que alimenta nosso template. Uma solução é remover o item da lista apenas quando a operação de deleção no servidor for bem sucedida. Para isso, podemos usar o boa e velha conhecida função splice para remover a foto deletada da lista:

// alurapic/client/app/listagem/listagem.component.ts

import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { FotoService } from '../foto/foto.service';
import { FotoComponent } from '../foto/foto.component';

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

    fotos: FotoComponent[] = [];
    service: FotoService;

    constructor(service: FotoService) {
        this.service = service;
        this.service.lista()
            .subscribe(
                fotos => this.fotos = fotos,
                erro => console.log(erro)
            );
    }

    remove(foto: FotoComponent): void {

        this.service.remove(foto)
             .subscribe(
                fotos => {
                    let indiceDaFoto = this.fotos.indexOf(foto);
                    this.fotos.splice(indiceDaFoto, 1);
                    console.log('Foto removida com sucesso');
                },
                erro => console.log(erro));
    }
}

Contudo, isso não parece ser suficiente, pois a view não foi atualizada, mesmo com essa alteração no modelo.

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