I have had a problem for a long time that I do not understand very well why it happens, I tried everything else, however I always find it in one way or another, let me explain.
I am developing a split App, Front End with React JS and ASP .net in the BackEnd, so far so good.
I designed a page in which what I am looking for is, Before the components of my page are displayed, I want to make 2 calls to my back end to bring me 2 different resources in JSON format, both resources of Type GET and I want this to be displayed information in my components. the information I ask for is nothing special, just simple JSON text strings like username, identifier, numbers etc.
To make the call to my backend I use AXIOS, and in this case I use PROMISE JavaScript in React.
To execute it when mounting my component, I make use of React's UseEffect, in this way I execute the 2 calls.
I'm not using Redux, I'm just using SessionStorage and LocalStorage, the logic in my head is as follows:
1.-if the sessionStorage called Client does not exist, I will execute the function GetCliente
2.- The GetCliente function makes calls to the API with AXIOS and brings me the information of the client
3.- When I bring it, I convert the JSON into a Javascript object with JSON.stringify and in this way I create the Client sessionStorage.
4.- When the Client sessionStorage is created, it will be mounted on a UseState called client whose initial state is null.
5.- When the client useState is filled, it will be painted on the page, to paint it I use this notation client?.username, to access its values and if it doesn't come, it won't mark me an error.
6.- When the sessionStorage called Client is created, if the user decides to "Refresh" the page, he will no longer have to make the API call because he is already registered on the page, so he will only have to mount the information of the sessionStorage in my UseState, this way I don't overload my server with requests.
Now here comes the tricky...
My logic works, I already have it implemented and it has worked, however the following errors start appearing.
1.- Sometimes, when I enter the page for the first time, of the 2 resources that I request, 1 does not arrive, I have 2 functions, getCliente() this brings me data from a client and getWarehouse() this brings me data from a warehouse.
sometimes the information from getCustomer does not arrive but the information from getWarehouse does, and on other occasions the information from getWarehouse does not arrive but the information from getCustomer does.
I have a button called close session that cleans the sessionStorage, when I try to enter the page again it does not bring me any of the 2 resources!
I went to the Network tab of my browser, and sometimes I see that my 2 resources are executed 2 times, according to what I know is by UseEffect, that it executes my function 2 times, however in the 2 occasions the request of my 2 resources are in status 304
sometimes when I go to the network tab, I see that one of my resources is in status 304, and then that same resource is executed again by the UseEffect and the status appears in 200, a sign that it was achieved but for some reason , it doesn't load into my SessionStorage! It appears to me that the client SessionStorage was created but it is empty!
I don't know what to do anymore, I have greatly simplified this logic at this point, however sometimes it works very well and other times it doesn't!
Now yes, I attach all the code, I don't really know what I'm doing wrong, even my backend doesn't do other things like verify token or something like that, it just asks for the resource and sends it but I don't understand why it keeps happening...
First Server code this is my endpoint that brings data from my store...
[HttpGet("almacen/{dbhandle:int}/{idcaja:int}")]
public ActionResult<string> getAlmacen(int dbhandle, int idcaja) {
string [] data = ConexionDB.Instance.Obtener_almacen_caja(dbhandle, idcaja);
var dataconvert = JsonConvert.SerializeObject(data);
return Ok(dataconvert);
}
this is my endpoint that brings my user data
[HttpGet("cliente/{dbhandle:int}")]
public ActionResult<String> getcliente(int dbhandle) {
string [] data = ConexionDB.Instance.Obtener_cliente(dbhandle);
var dataconvert = JsonConvert.SerializeObject(data);
return Ok(dataconvert);
}
both endpoints work, both with PostMan I have tested it
Now code in React...
const VentasMostrador = () => {
//varibles de estado useState
const [cliente, setcliente] = useState(null);
const [almacen, setalmacen] = useState(null);
const [cajero, setcajero] = useState(null);
const [productos, setproductos] = useState([]);
const [cambio, setcambio] = useState(false);
const [total, setTotal] = useState(0);
const [show, setShow] = useState(false);
const [productoSeleccionado, setProductoSeleccionado] = useState(null);
const [seriesylotes, setseriesylotes] = useState(null);
if(!sessionStorage.getItem("ID_CAJA")){
window.location = "/PaginaPrincipal";
}
const getCliente = async () => {
let user = JSON.parse(localStorage.getItem("datauser"));
const promise = await axios.get("https://localhost:5001/api/ventasmostrador/cliente/"+user.DbHandle);
if(promise){
let data = promise.data;
let infodata = { id: data[0], nombre: data[1], codigo: data[2] };
sessionStorage.setItem("GET_CLIENTE", JSON.stringify(infodata));
setcliente(JSON.parse(sessionStorage.getItem("GET_CLIENTE")));
} else {
console.log("no se pudo cargar los datos de almacen...");
}
};
const getAlmacen = async () => {
let user = JSON.parse(localStorage.getItem("datauser"));
let caja = JSON.parse(sessionStorage.getItem("ID_CAJA"));
const promise = await axios.get("https://localhost:5001/api/ventasmostrador/almacen/"+user.DbHandle+"/"+caja);
if(promise){
let data = promise.data;
let infodata = {
id: data[0],
caja: data[1],
idalmacen: data[2],
nombrealmacen: data[3],
};
sessionStorage.setItem("GET_ALMACEN", JSON.stringify(infodata));
setalmacen(JSON.parse(sessionStorage.getItem("GET_ALMACEN")));
} else {
console.log("no se pudo cargar los datos de almacen...");
}
};
now to execute these 2 functions I make use of UseEffect.
useEffect(() => {
let datauser = JSON.parse(localStorage.getItem("datauser"));
setcajero(datauser.Nombrecajero);
}, [])
useEffect(() => {
if(!sessionStorage.getItem("GET_CLIENTE")){
getCliente();
} else {
setcliente(JSON.parse(sessionStorage.getItem("GET_CLIENTE")));
}
console.log("cuanto se ejecuta x1...");
}, []);
useEffect(() => {
if(!sessionStorage.getItem("GET_ALMACEN")){
getAlmacen();
console.log("cuanto se ejecuta x2...");
} else {
setalmacen(JSON.parse(sessionStorage.getItem("GET_ALMACEN")));
}
}, [])
Evidence of all my explanation...
This image is when I entered the application for the first time, here it executed perfectly and the data came out.
here the information is painted in my component, all good and in the tab where sessionStorage is located both objects are created and filled.
Here comes the problem, when I press the button, logout, and I leave this page, and try to enter again so that everything can be reloaded, it stops working or 1 resource, or another resource or BOTH :(
If I check the network tab, they appear to me that they arrived!
So I don't know what to do, I know the explanation is too long and tedious but this frustrates me, I don't know if the controller, useEffect, my javascript function or the promise is wrong.
If anyone reads this please help :(