donc j'utilise une fenêtre contextuelle pour connecter mes utilisateurs avec Firebase:
return action$.pipe( ofType('SET_NEW_USER_INFORMATION'), mergeMap((action) => { return from( firebaseApp.database().ref(firebaseRef).update(userInformation), ).pipe( mergeMap(() => { return [updatedUserInformationSuccess()] }), catchError((error) => of(updatedUserInformationFailure(error))), ) }), )
donc si je supprime window.location.href = 'visité'
ceci tout fonctionne bien et il se met dans firebase. Je fais probablement quelque chose de stupide mais je ne comprends pas comment attendre que cette fonction déclenche setNewUserInformation
et se termine avant de passer à la nouvelle page?
code de fonction:
export const setNewUserInformation = (userId) => { return { type: 'SET_NEW_USER_INFORMATION', userId, } }
ceci a alors une épopée observable redux qui l'écoute:
const loginToApp = (provider) => { firebaseApp .auth() .signInWithPopup(provider) .then(async (result) => { if (result.additionalUserInfo.isNewUser) { // problem is this line await setNewUserInformation(result.user.uid) } const { user } = result setUser(user) // and this line window.location.href = 'newRoute' }) .catch((error) => { console.log('ERROR:', error) }) }
4 Réponses :
Utilisez-le comme ci-dessous
const loginToApp = (provider) => { firebaseApp .auth() .signInWithPopup(provider) .then(async (result) => { new Promise((resolve, reject) => { if (result.additionalUserInfo.isNewUser) { // problem is this line setNewUserInformation(result.user.uid) } const { user } = result resolve(user) }).then((user)=>{ setUser(user) // and this line window.location.href = 'newRoute' }) }) .catch((error) => { console.log('ERROR:', error) }) }
Parce que sur puis
vous pouvez retourner une promesse et résoudre plus tard. Nous pourrions réécrire le code ci-dessus comme ceci ci-dessous:
const loginToApp = (provider) => { firebaseApp .auth() .signInWithPopup(provider) .then((result) => { if (result.additionalUserInfo.isNewUser) { // return for next resolve function return setNewUserInformation(result.user.uid).then(() => result); } return result; }) .then((result) => { // after all above promises resolve const { user } = result setUser(user) // and this line window.location.href = 'newRoute' }) .catch((error) => { console.log('ERROR:', error) }) }
Utilisez-vous React? Si oui, vous pouvez simplement utiliser didUpdate Cycle pour acheminer vers une nouvelle URL après l'envoi d'une action réussie. Déplacez votre "window.location.href = 'newRoute'" sous le contrôle ComponentDidUpdate avec accessoires.
J'utilise un composant fonctionnel. Je sais que je peux toujours le faire avec eux mais le problème est avec mon redux observable
Je pense, de toute façon
setNewUserInformation ()
est un créateur d'action, qui est sync. Vous n'avez pas besoin de l'attendre car cela ne renvoie rien d'utile à votre logique. Ce que vous devez faire, c'est déplacer window.location.href = 'newRoute'
pour séparer la logique et la faire dépendre de l'état renvoyé par les créateurs d'action updatedUserInformationSuccess ()
et updatedUserInformationFailure (Erreur). Si votre composant est fonctionnel, mettez cette logique dans un useEffect
. S'il s'agit d'un composant de classe, utilisez la méthode du cycle de vie ComponentDidUpdate
.
ah cela m'a aidé. déplacé vers useEffect, puis en attente de mise à jour de redux avant de changer de page.cheers bro! marquez la question si cela ne vous dérange pas;)
à quoi ressemble la fonction?
@Ifaruki J'ajouterai du code. mais c'est juste un créateur d'action qui a alors un redux observable en l'écoutant
@Ifaruki a ajouté du code
le fait est que vous utilisez
await
sur une fonction avec ne renvoie PAS de promesse.Je pensais que
from
renvoie une promesse en redux-observableEh bien, vous utilisez
await
sursetNewUserInformation
qui renvoie un objet. wait n'attendra que cette fonctionah ouais, tu as raison. hmm, je me demande comment je peux résoudre ce problème