I have the following js file where I’m trying to replicate a request I made through postman to the api url http://localhost:1777/api/test
My objective was to simulate that request and have the response inside an object that I could see in the browser console.
My poblem is that the browser console shows two objects instead of one (it’s duplicated basically). That makes me believe that the line "console.log(simulatedResponse)" is running twice but I’m having trouble fixing the problem to have it only run once.
my js file code:
import React, { useEffect, useState } from 'react';
import { MyEditor } from '@Editor/my-editor';
function MedEditor() {
const URL = 'http://keycloak:1901/auth/realms/myEditor/protocol/openid-connect/token';
const [token, setToken] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const getToken = async () => {
const params = new URLSearchParams();
params.append('grant_type', 'client_credentials');
params.append('client_id', 'myEditor_cli_client');
params.append('client_secret', 'myEditor_cli_client_secret');
const response = await fetch(URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params,
});
const data = await response.json();
setToken(data.access_token);
setIsLoading(false);
};
getToken();
}, []);
useEffect(() => {
if (token) {
simulateApiRequest();
}
}, [token]);
const simulateApiRequest = async () => {
const postData = {
data: {
correlationId: 123,
subjectId: "01",
text: "test text"
}
};
const response = await fetch('http://localhost:1777/api/test', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
},
body: JSON.stringify(postData),
});
if (response.ok) {
const simulatedResponse = await response.json();
console.log(simulatedResponse); // Display the simulated response in the console
// Now you can use the simulated response as needed
} else {
console.error('API request failed:', response.status, response.statusText);
}
};
return (
<div className="editor-container">
{isLoading ? (
<p>Loading...</p>
) : token ? (
<MedNoteEditor tokenProvider={{ getToken: () => token }} />
) : (
<p>No token available.</p>
)}
</div>
);
}
export default MedEditor;
I tried to change the useffect fuction but so far haven’t been successful. Can anyone help me fix the issue?
2
Answers
In your
if(response.ok){…}
loop, you may be executing the request twice, one more than what you want. You can simplyconsole.log(response.json())
directly instead of adding it another variable, that re-invokes a request to be sent.The reason you’re seeing the console.log(simulatedResponse) called twice is because you have two separate useEffect hooks in your MedEditor component. The first useEffect hook is responsible for making the API call and fetching the token, and the second useEffect hook is triggered when the token state changes.
In your code, the first useEffect hook is fetching the token, and as a result, it triggers the second useEffect hook when the token state is updated. This is why you see the console.log(simulatedResponse) being called twice:
The first call happens when the token is successfully fetched in the first useEffect hook and updates the token state.
The second call happens when the token state changes, and the second useEffect hook is triggered to simulate the API request.
To prevent the double call to console.log(simulatedResponse), you can update your code as follows:
By adding the check for !isLoading, you ensure that the second useEffect hook will only be triggered when the token is available and loading has finished.
Remember that React will call all useEffect hooks that depend on the variable when it changes. Since you have a dependency on the token in both useEffect hooks, they are both being executed when the token changes.