Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

POST e PUT está salvando apenas _id

Olá!

A partir da Aula 04, etapa vídeo 03, meu código passou a ter um comportamento estranho.

As requisições POST e PUT são feitas para o servidor e este parece guardar somente a propriedade _id, sem guardar titulo e url, por exemplo.

Com isto, tenho erros na listagem, que só volta a funcionar se eu fizer uma requisição manual DELETE (com curl ou Insomnia) no servidor excluindo o último objeto inserido ou alterado.

cadastro.component.ts

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

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

    foto: FotoComponent = new FotoComponent();
    meuForm: FormGroup;
    service: FotoService;
    route: ActivatedRoute;
    router: Router;

    constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute, router: Router) {
        this.service = service;
        this.route = route;
        this.router = router;
        this.route.params.subscribe(params => {
            console.log(params);
            let id = params['id'];
            if (id) {
                this.service.buscaPorId(id)
                    .subscribe(foto => this.foto = foto, error => console.log(error));
            }
        });
        this.meuForm = fb.group({
            titulo: ['', Validators.compose(
                [Validators.required, Validators.minLength(4)]
            )],
            url: ['', Validators.required],
            descricao: []
        });
        console.log(this.foto);
    }

    cadastrar(event) {
        console.log(this.foto);
        event.preventDefault();
        this.service.cadastra(this.foto).subscribe(() => {
            this.foto = new FotoComponent();
            console.log('Falta salva com sucesso!');
            this.router.navigate(['']);
        }, erro => {
            console.error(erro)
        });
    }
}

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 {
    http: Http;
    headers: Headers;
    url: string = 'v1/fotos';

    constructor(http: Http) {
        this.http = http;

        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
    }

    cadastra(foto: FotoComponent): Observable<Response> {
        if (foto._id) {
            console.log(foto);
            return this.http.put(this.url + '/' + foto._id, JSON.stringify(foto),
                { headers: this.headers });
        } else {
            console.log(foto);
            return this.http
                .post(this.url, JSON.stringify(foto), { headers: this.headers });
        }
    }

    lista(): Observable<FotoComponent[]> {
        return this.http
            .get(this.url)
            .map(res => res.json());
    }

    remove(foto: FotoComponent) {
        return this.http
            .delete(this.url + '/' + foto._id);
    }

    buscaPorId(id): Observable<FotoComponent> {
        return this.http.get(this.url + '/' + id).map(res => res.json());
    }
}

Erros em listagem.component.html

EXCEPTION: Error in http://localhost:3000/app/listagem/listagem.component.html:16:16 caused by: Cannot read property 'toLowerCase' of undefined

Porque não encontra a propriedade titulo usada no pipe.

import { Pipe, PipeTransform } from '@angular/core';
import { FotoComponent } from './foto.component';

@Pipe({
    name: 'filtroPorTitulo'
})

export class FiltroPorTitulo implements PipeTransform {

    transform(fotos: FotoComponent[], digitado: string) {
        digitado = digitado.toLowerCase();
        return fotos.filter(foto => foto.titulo.toLowerCase().includes(digitado));
    }
}

Veja como os objetos são retornados pela requisição GET /v1/fotos

[
    {
        "_id": "7F7UbxuylTp8gRqy"
    },
    {
        "_id": "mD3SkInMvQEP9MZr"
    },
    {
        "titulo": "Elefante de Fraldinha",
        "url": "https://www.infoescola.com/wp-content/uploads/2016/12/elefante-asiatico-198685685.jpg",
        "descricao": "Elefante",
        "_id": "8Gg5wfxl4VWCrgGZ"
    }
]

E o payload de uma das requisições POST. Request URL:http://localhost:3000/v1/fotos Request Method:POST Status Code:200 OK Payload:

{"titulo":"Flamengo","url":"https://www.torcedores.com/content/uploads/2017/11/flamengo-ao-vivo.jpg"}

Response:

"7F7UbxuylTp8gRqy"
5 respostas
solução!

Boa noite. Você está passando um header nulo na sua requisição. Você está declarando o header como variável e não propriedade da classe. Dai, na hora salvar está usando o header da propriedade da classe que é nulo.

O correto é

constructor(http: Http) {
        this.http = http;

        this.headers = new Headers();
        this.headers.append('Content-Type', 'application/json');
    }

Flávio, continuei a lição a partir da aula 5, e fiz download do código que é fornecido ali.

Mesmo assim me deparo com o mesmo problema, mesmo lá já estando o código conforme você publicou aqui.

Continua sendo salvo apenas a propriedade _id em data.db.

Desconsidere a mensagem anterior, acho que havia esquecido de recompilar o TS para alguma coisa que escrevi. Testei e agora funcionou. Obrigado pela ajuda!

Aqui funcionou. Aliás, você é o primeiro aluno em mais de 2000 alunos que teve esse problema.

Se você já gravou os dados só com id eles continuaram sem id. Só os novos dados serão salvos corretos. Será que é isso? Eu não sei ainda o que pode está ocasionando esse problema já que você disse que está com o código correto. Há alguma mensagem no console do Chrome ?

Que boa notícia! Fiquei preocupado porque não conseguia enxergar o problema.

Sucesso e bom estudo meu aluno!