1
votes

Comment attendre une action asynchrone réussie avant de changer d'URL?

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)
        })
}


7 commentaires

à 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-observable


Eh bien, vous utilisez await sur setNewUserInformation qui renvoie un objet. wait n'attendra que cette fonction


ah ouais, tu as raison. hmm, je me demande comment je peux résoudre ce problème


4 Réponses :


0
votes

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)
    })
  }


0 commentaires

0
votes

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)
        })
}


0 commentaires

0
votes

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.


2 commentaires

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



1
votes

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 .


1 commentaires

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;)