Un error común entre los desarrolladores es asumir que fetch hará un promise reject al recibir un status de error de HTTP tal como lo haría un XMLHttpRequest. Esto tal vez se deba a la costumbre de usar jQuery Ajax, donde teníamos métodos como .success() y .fail(). Para fetch, este no es el caso, dado que, solo hace un reject cuando exista un error en la red. Si el servidor está trabajando de manera correcta nos responderá la petición realizada, así sea con un status 400 o 500 y fetch lo tomará como promise resolve.
Bien, veamos entonces cómo utilizar fetch.
Fetch puede funcionar con solo un parámetro, la url.
let url = 'http://someURL.com' ; fetch(url).then(response => console.log(response));
Sin embargo, es común olvidar agregar las credenciales o el Content-Type, para ello podemos enviar do parámetros url y request.
let headers = new Headers(); headers.append('Content-Type', 'application/json'); let request = { headers, method:'POST', body: '{"foo":"bar"}' } let url = 'http://someURL.com'; fetch(url,request).then(response => console.log(response));
El caso anterior tiene una alternativa al usar un objeto Request para enviar solo un parámetro .
const request = new Request('http://webapi.com', { method: 'POST', body: '{"foo":"bar"}' }); fetch(request) .then(response => console.log(response)) .catch(error => console.error(error));
Ahora veamos como manejar los errores para ello es necesario recordar que fetch regresa un objeto del tipo Response. Response tiene varias propiedades y nosotros utilizaremos dos propiedades Response.ok y Response.status.
La manera fácil y rápida de hacer esto es utilizar la propiedad Response.ok esta propiedad es de solo lectura y será true solo en los status del rango 200-299, así nuestro código quedará de la siguiente manera:
fetch(request) .then(response => { if (!response.ok) throw Error(response.status); return response; }) .then(response => console.log("ok")) .catch(error => console.log(error)); //en catch decidimos que hacer con el error, aquí recibimos response.status
Dentro de throw Error(…) podemos regresar statusText o status, status es el número del código de error (200, 404, 500 etc), y statusText nos regresa el nombre asociado al código de error.
Para hacer nuestro código reutilizable dividiremos las funciones
const handleError = (response) => { if (!response.ok) throw Error(response.status); return response; } const handledFetch = (request) => { return fetch(request) .then(handleErrors) }
De esta manera podemos utilizar nuestra función desde cualquier parte de la aplicación
const apiGetSomething = () => { let headers= new Headers(); headers.append('Content-Type', 'application/json'); const request = new Request('http://webapi.com', { method: 'POST', body: '{"foo":"bar"}' , headers }); return handledFetch ( request ) .then(response => response.json()) };
El hecho de que fetch no maneje los errores es de cierta manera una ventaja para los programadores que les gusta tener más control sobre su código ya que con fetch tenemos la oportunidad de decidir cómo lidiar con los problemas. Además, si comparamos fetch con XMLHttpRequest, fetch nos ofrece una forma de hacer peticiones más legible.
Puedes consultar la documentación oficial de fetch en lo siguientes links: