ReactJS HTTP Client con mensajes globales con Toastify
Aquí les presento un proyecto ReactJS con la configuración de un HTTP client que pueden utilizar para hacerles peticiones a las aplicaciones backend. Además le introduje un mecanismos de mensajes en forma de toast que se ejecuta en un entorno global en la aplicación web.
1- Lo primero es crear el proyecto y agregar las dependencias:
- create-react-app react-httpclient-toast
- cd react-httpclient-toast
- npm install
- npm install react-toastify
2- Agregar el componente Toast en el App.js el componente raíz de nuestra App
#src/App.js
import React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.min.css'
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
function App() {
return (
<div className="masthead">
<ToastContainer position={toast.POSITION.BOTTOM_RIGHT} />
<Router history={history}>
<Switch>
<Route path={`/`} component={/* Componente de Inicio */} />
</Switch>
</Router>
</div>
);
}
3- Luego creamos el HTTP Client que usaremos en los componentes para hacerle peticiones al backend
#src/core/http-client.js
import storage from "../helper/storage";
import { toast } from "react-toastify";
const post = (endpoint, body) => {
const requestOptions = {
method: 'POST',
headers: header(),
body: JSON.stringify(body)
};
return fetch(process.env.REACT_APP_BACKEND + endpoint, requestOptions).then(handleResponse)
}
const put = (endpoint, body) => {
const requestOptions = {
method: 'PUT',
headers: header(),
body: JSON.stringify(body)
};
return fetch(process.env.REACT_APP_BACKEND + endpoint, requestOptions)
.then(handleResponse)
}
const get = (endpoint) => {
const requestOptions = {
method: 'GET',
headers: header(),
};
return fetch(process.env.REACT_APP_BACKEND + endpoint, requestOptions)
.then(handleResponse)
}
const del = (endpoint) => {
const requestOptions = {
method: 'DELETE',
headers: header()
};
return fetch(process.env.REACT_APP_BACKEND + endpoint, requestOptions)
.then(handleResponse)
}
const header = () => {
let token;
let data = storage.load(storage.keys.auth)
if (data && data.access_token) {
token = data.access_token
}
let header = { 'Content-Type': 'application/json', 'Accept': 'application/json' };
if (token) {
Object.assign(header, { 'Authorization': 'Bearer ' + token })
}
return header;
}
const handleResponse = (response) => {
if (!response.ok) {
mapErrorToMessage(response.clone())
throw response
} else {
return response.json().then(data => {
return data;
});
}
}
const mapErrorToMessage = (response) => {
let code = response.status
switch (code) {
case 404:
toast.error( 'Element not found')
break;
case 500:
toast.error( 'Internal Error Server (This message is only for development proyect)')
break;
default:
return response.json().then(data => {
if (!data.message) {
toast.error(response.statusText)
} else {
toast.error( data.message)
}
});
}
}
export default { post, put, del, get, mapErrorToMessage }
Creamos un archivo de enviroment para poner la configuración del proyecto
#.env.production
REACT_APP_BACKEND=https://api.backend.domain/api/v1/
PUBLIC_URL=https://frontend.domain/
#.env.development
REACT_APP_BACKEND=http://localhost:5000/
PUBLIC_URL=http://localhost:3000/
Con esta configuración cada vez que el backend con devuelva un error por ejemplo 404 o 500 se activará un mensaje global en la aplicación.