Reputation: 741
I'm finishing up an app in which I want to hide my GoogleMap API key behind my secure API. My intention is to call for the API key once I verify that I have an authenticated user. The problem is that between the async calls, changes are not reflected with the state change.
This is what I am doing:
export default function App() {
const [dateRange, setDateRange] = useState(initialDateRange);
const [formState, updateFormState] = useState(initialFormState);
const [user, setUser] = useState(null);
const [googleApiKey, setGoogleApiKey] = useState(null);
useEffect(() => {
async function updateAuth() {
try {
await checkUser();
await getGoogleApiKey();
await setAuthListener();
} catch (error) {}
}
updateAuth();
}, []);
async function checkUser() {
try {
const user = await Auth.currentAuthenticatedUser();
setUser(user);
if (user !== authenticatedUser) {
updateFormState(() => ({
...formState,
authenticatedUser: user
}));
}
} catch (error) {
console.log(error);
}
}
async function getGoogleApiKey() {
const googleApiUrl = `${process.env.REACT_APP_API_PATH}apikey?googleapikey=true`;
try {
console.log('USER_USER_USER', user);
const apiKey = await fetch(googleApiUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: user.signInUserSession.idToken.jwtToken
}
});
console.log('GOT_GOOGLE_API_KEY', apiKey);
setGoogleApiKey(apiKey);
} catch (error) {
console.log(error);
}
}
async function setAuthListener() {
Hub.listen('auth', (data) => {
const event = data.payload.event;
switch (data.payload.event) {
case 'signOut':
console.log('signing out...');
console.log(event);
updateFormState(() => ({
...formState,
username: '',
password: '',
email: '',
authenticatedUser: null
}));
break;
default:
break;
}
});
}
But I am getting the error:
USER_USER_USER null
App.js:78 TypeError: Cannot read property 'signInUserSession' of null
at getGoogleApiKey (App.js:72)
at updateAuth (App.js:42)
If this is the wrong paradigm, I'd appreciate any alternatives!
Upvotes: 3
Views: 991
Reputation: 2613
When setUser
is called, the user
variable still holds old user
information (null
in this case), regardless of async/await
:
await checkUser(); // setUser(something) will not happen until next run
await getGoogleApiKey(); // user is still null
await setAuthListener();
One other choice would be to add another effect when user
changes:
useEffect(() => {
if (user) {
getGoogleApiKey();
}
}, [user]);
Or, call getGoogleApiKey
with the parameter:
const user = await checkUser(); // return user
await getGoogleApiKey(user);
await setAuthListener();
Since the logic gets complex, I would suggest trying the useReducer hook because dispatch simplifies this complex back and forth scenarios.
Upvotes: 4