servico_de_remocao - VWJavascript/Alurapic GitHub Wiki
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));
}
}
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.