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

Requisição tipo POST: Faz sentido tentar converter a resposta do servidor em JSON?

Olá pessoal!

Esse exercicio me deixou com uma séria dúvida, reparem nesse trecho onde o professor chama o método post:

new HttpService()
                .post('/negociacoes', negociacao)
                .then(() => {
                    inputData.value = '';
                    inputQuantidade.value = 1;
                    inputValor.value = 0.0;
                    inputData.focus();
                    alert('Negociação enviada com sucesso');
                })
                .catch(erro => alert(`Não foi possível enviar a negociação: ${erro}`));

Agora vejam o próprio método post:

post(url, dado) {


        return new Promise((resolve, reject) => {

            let xhr = new XMLHttpRequest();
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-type", "application/json");
            xhr.onreadystatechange = () => {

                if (xhr.readyState == 4) {

                    if (xhr.status == 200) {
        //////aqui está minha dúvida
                        resolve(JSON.parse(xhr.responseText));
                    } else {

                        reject(xhr.responseText);
                    }
                }
            };
            xhr.send(JSON.stringify(dado)); // usando JSON.stringify para converter objeto em uma string no formato JSON.
        });

    }

Vejam que o professor faz uma requisição do tipo POST, então ele tenta atribuir ao resolve da Promise a resposta do servidor, que no caso é undefined, e além disso tenta converter pra JSON o undefined que veio do servidor, essa peripécia de tentar converter undefined em JSON por si só já tá gerando erro no console, mas mesmo se isso funcionar reparem que o then lá na chamada do método não espera nenhum JSON...

Ou eu estou enganado e confuso, ou tem algo estranho nesse exercicio/código, algum manjão aí pode jogar uma luz aqui?

3 respostas
solução!

Fala aí Rafael, tudo bem? Vamos por partes:

Vejam que o professor faz uma requisição do tipo POST, então ele tenta atribuir ao resolve da Promise a resposta do servidor, que no caso é undefined

É uma boa prática realizar essa conversão, pois a gente não consegue trafegar um objeto JSON na rede, geralmente quando a resposta chega a mesma está em algum formato diferente de JSON.

O único problema é não tratar se a resposta está como undefined, algo assim resolveria o problema:

resolve(JSON.parse(xhr.responseText || '{}'))

Se o responseText for undefined ele vai parsear o objeto vazio.

mas mesmo se isso funcionar reparem que o then lá na chamada do método não espera nenhum JSON

A função .post é genérica, então, por isso ela precisa devolver a resposta no resolve da Promise, se quem usou ela vai fazer uso desse valor, ai já é outros quinhentos.

Espero ter ajudado.

Colocar o objeto vazio como opção de retorno do resolve funcionou direitinho bicho, valeuuu!

Só mais uma pergunta cara, quando dou um log na resposta do servidor de uma requisição bem sucedida recebo um undefined, mas indo em network>response do navegador vejo que e servidor me devolveu uma string "Negociação recebida", porque o meu log imprime undefined ao invés de me trazer essa mensagem?

Tente dar um log no xhr.responseText para ver o que será logado:

console.log(xhr.responseText)

Se a resposta for logada corretamente, o problema pode ser como você está tentando consumir essa informação.

Outro detalhe: Dá uma olhada na Fetch API, ela é o sucessor do XMLHttpRequest.

Talvez faça mais sentido você mudar para ela.

Espero ter ajudado.