How to handle multiple api calls in the same render ?
Example :
I want to get some info from first API call like this for example :
const getUserInfo = async () => { const response = await axios .get(`${API}/api/tenants/${app.tenant}/users/me`, axiosConfig) .then((r) => { return r.data; }) .catch((e) => { console.log("ERORR", e); }); return response; }; const USER_INFO_SETTER = async () => { const fulldata = await getUserInfo(); setUsername(fulldata.username); setDisplayname(fulldata.display_name); setId(fulldata.id); getAvatarId(fulldata.profile_image); setFirstName(fulldata.first_name); setLastName(fulldata.last_name); }; useEffect(() => { USER_INFO_SETTER(); }, [isFocused]);
and i want to instantly use it for the next API CALL coming under this call
example :
const GET_ACTIVE_PROFILE_PICTURE = async () => { try { const rez = await axios .get(`${API}/api/documents/document/${user.avatar_id}`, axiosConfig) .then((r) => { return r.config.url; }) .catch((e) => { console.log("ERROR", e); }); return rez; } catch { console.log("error"); } }; const avatarSetted = async () => { const avatarLink = await GET_ACTIVE_PROFILE_PICTURE(); setProfileImage(avatarLink); }; useEffect(() => { avatarSetted(); console.log("123"); }, []);
Soo the question is how to use information that i get inside first API call just after that in the api call below. because wihtout that information for example user.id_picture my second api call will return 500.
Thanks for the help 🙂
Advertisement
Answer
Firstly, I would create a couple of functions like so:
const getUserInfo = () => { // This contains the axios request and returns the response. }; const getActiveProfilePicture = () => { // This contains the axios request and returns the response. }; const fetchUserInfo = () => { // This calls the getter and uses the response to update state. }; const fetchActiveProfilePicture = () => { // This calls the getter and uses the response to update state. };
I would also introduce 2 state variables, you may already have these so this step may be unnecessary.
const [avatarId, setAvatarId] = useState(null); const [profileImage, setProfileImage] = useState(null);
Fill out the logic for your functions you added above.
const fetchUserInfo = useCallback(async () => { const response = await getUserInfo(); // Perform all state updates. setAvatarId(response.profile_image); }, []); const fetchActiveProfilePicture = useCallback(async () => { const response = await getActiveProfilePicture(); // Perform all state updates. setProfileImage(response); }, []);
Next, create two useEffects
:
- When the component mounts, call
fetchUserInfo
. - When the
avatarId
has been retrieved and ultimately set in state, callfetchActiveProfilePicture
.
useEffect(() => { fetchUserInfo(); }, [fetchUserInfo]); useEffect(() => { if(avatarId) { fetchActiveProfilePicture(); } }, [fetchActiveProfilePicture, name]);
You’ll run into some warnings from eslint (react-hooks/exhaustive-deps
) within this example about either wrapping functions in useCallback
or placing the logic directly in useEffect
. Just a heads up.