Как избежать наблюдаемой задержки в угловых или сделать так, чтобы моя функция вызывалась только тогда, когда наблюдаемая готова - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть функция входа в систему, которая вызывает метод Firebase SDK для аутентификации по электронной почте.Этот метод Firebase возвращает ненулевое значение Promise, равное UserCredential, так говорится в документах Firebase.Поэтому я использую .then(), чтобы дождаться, пока пользователь войдет в систему, аутентифицируется, а затем console.log его информации и перенаправит на дом.К сожалению, это не работает.Я получаю неопределенное значение от console.log(value.email); в консоли, not working от

if (this.userDetails) {
console.log("hello im user" + " " + email);
} else {
console.log("not working");
}

и errorTypeError: Cannot read property 'router' of undefined от:

.catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log("error" + error);
    });

, затем сразу через одну или две секунды, наконец, начинаетсяработает, печатает hello im user lajmis@mail.com из

constructor(private _firebaseAuth: AngularFireAuth, private router: Router) {
    this.user = _firebaseAuth.authState;
    this.loggedIn = !!sessionStorage.getItem('user');

    this.user.subscribe(
        (user) => {
          if (user && user.uid) {
            this.userDetails = user;
            var email = this.userDetails.email;
            console.log("hello im user" + " " + email);
            this.setCurrentUser(email);
            this.loggedIn = true;
            console.log(this.userDetails);

          } else {
            this.userDetails = null;
          }
        }
      );
  }

и this.userDetails.

Почему это происходит?Вот полный код:

export class AuthService {
  private user: Observable<firebase.User>;
  private userDetails: firebase.User = null;
  public loggedIn = false;

  constructor(private _firebaseAuth: AngularFireAuth, private router: Router) {
    this.user = _firebaseAuth.authState;
    this.loggedIn = !!sessionStorage.getItem('user');

    this.user.subscribe(
        (user) => {
          if (user && user.uid) {
            this.userDetails = user;
            var email = this.userDetails.email;
            console.log("hello im user" + " " + email);
            this.setCurrentUser(email);
            this.loggedIn = true;
            console.log(this.userDetails);

          } else {
            this.userDetails = null;
          }
        }
      );
  }

  // Set current user in your session after a successful login
    setCurrentUser(email: string): void {
        sessionStorage.setItem('user', email);
        this.loggedIn = true;
    }

    // Get currently logged in user from session
    getCurrentUser(): string | any {
        return sessionStorage.getItem('user') || undefined;
    }

    isLoggedIn() {
    return this.loggedIn;
    }

  logUserIn(email, pass) {
    firebase.auth().signInWithEmailAndPassword(email, pass).then(function(value) {

        console.log(value.email);
        this.router.navigate(['']);

    }).catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log("error" + error);
    });
if (this.userDetails) {
console.log("hello im user" + " " + email);
} else {
console.log("not working");
}
}

1 Ответ

0 голосов
/ 12 декабря 2018

logUserIn не блокирует - поэтому рабочий процесс будет;

  • вызов constructor
  • вызов this.user.subscribe
  • вызов logUserIn
  • вызов firebase.auth().signInWithEmailAndPassword
  • вызов if (this.userDetails)
  • получение ответа от firebase.auth().signInWithEmailAndPassword
  • вызов .then(function(value) {
  • вызов this.router.navigate(['']);
  • получает ответ от this.user.subscribe

Поэтому console.log выдаст not working, а через несколько секунд this.user.subscribe получит объект user.

router недоступен, потому что вы не используете arrow function.Используйте arrow function для поддержки доступа к this.

Возможно, попробуйте рабочий процесс, такой как следующий:

constructor(private _firebaseAuth: AngularFireAuth, private router: Router) {
  this.user = _firebaseAuth.authState;
  this.loggedIn = !!sessionStorage.getItem('user');

  this.user
    .subscribe(user => {
      console.log('constructor user: ' + user);
      this.updateUser(user);
    });
}

updateUser(user) {
  if (user && user.id) {
    this.userDetails = user;
    var email = this.userDetails.email;
    console.log("hello im user" + " " + email);
    this.setCurrentUser(email);
    this.loggedIn = true;
    console.log(this.userDetails);
  } else {
    this.userDetails = null;
  }
}

logUserIn(email, pass) {
  firebase.auth().signInWithEmailAndPassword(email, pass)
    .then(user => {
      console.log('logUserIn: ' + user);

      this.updateUser(user);

      this.router.navigate(['']);
    })
    .catch(error => {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log("error" + error);
    });
}

Таким образом, logUserIn и constructor могут обновлятьuserDetails при получении пользовательского объекта от Firebase.

Это также позволит избежать перенаправления до установки this.userDetails.

...