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 :)
CodePudding user response:
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.