Асинхронный вызов двух функций в Angular 2 с использованием обещания

У меня есть следующий метод в auth.nav.service.ts:

 public login () {
  this.authService.login();
  this.navService.redirectAfterLogin();
}

в nav.service.ts:

public redirectAfterLogin () {
  let nav = this.app.getRootNav();
  nav.setRoot(TabsPage);
  nav.popToRoot();
}

В Auth.service.ts:

public login() {
  const client = new Auth0Cordova(auth0Config);

  const options = {
    scope: 'openid profile offline_access'
  };

client.authorize(options, (err, authResult) => {
  if(err) {
    throw err;
  }

  this.setIdToken(authResult.idToken);
  this.setAccessToken(authResult.accessToken);

  const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
  this.setStorageVariable('expires_at', expiresAt);

  this.auth0.client.userInfo(this.accessToken, (err, profile) => {
    if(err) {
        throw err;
    }

    profile.user_metadata = profile.user_metadata || {};
    this.setStorageVariable('profile', profile);
    this.zone.run(() => {
        this.user = profile;

      });

    });

  });
}

Я хочу, чтобы функция входа в систему выполнялась успешно, а функция RedirectAfterLogin. Как я могу сделать это с Promise ? Я использую Angular 2, Ionic-Native 3 и auth0.


person user666    schedule 15.07.2017    source источник
comment
Этот? stackoverflow.com/questions/39645491/   -  person AJT82    schedule 15.07.2017
comment
@ AJT_82 AJT_82, спасибо, я наконец-то выполнил свое обещание, у меня была проблема с областью действия переменных внутри области «тогда».   -  person user666    schedule 16.07.2017


Ответы (2)


Я заставил его работать с обещанием и исправлением области переменных (это) внутри тогдашней области.

auth.view.service.ts

 public login () {
  var t = this; // this scope is lost inside the then.
  this.authService.login().then(function (response){
    t.navService.redirectAfterLogin();
  });
 }

auth.service.ts

 public login () {
return new Promise<any>((resolve, reject) => {

  const client = new Auth0Cordova(auth0Config);

  const options = {
    scope: 'openid profile offline_access'
  };

  client.authorize(options, (err, authResult) => {
    if(err) {
      throw err;
    }
    this.setIdToken(authResult.idToken);
    this.setAccessToken(authResult.accessToken);

    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
    this.setStorageVariable('expires_at', expiresAt);

    this.auth0.client.userInfo(this.accessToken, (err, profile) => {
      if(err) {
        throw err;
      }

      profile.user_metadata = profile.user_metadata || {};
      this.setStorageVariable('profile', profile);
        this.zone.run(() => {
          this.user = profile;
          resolve(profile);
        }); // end zone run

      }); // end userInfo

    }); // end authorize
  }); // end Promise
} // end login

(Дайте мне знать в комментариях, может ли быть лучшая практика) См.:

Как дождаться функции завершить его выполнение в angular 2.?

javascript, обещания, как получить доступ к переменной this внутри а затем область

person user666    schedule 16.07.2017

Обновите, вы должны разместить перенаправление при успешной аутентификации

public login () {
  this.authService.login();
  ///////////////// remove it 
}

Поместите его в метод Authservice login().

 login(){
     this.redirectAfterLogin ()
 }

Или верните логическую переменную из метода входа в систему в AuthService.

 login() :boolean {
  //// your code 
   if(success) return true; 
   else return false;

 }

В вашем NavService

public login () {
  if(this.authService.login()){
       this.redirectAfterLogin ();
 }
person Aravind    schedule 15.07.2017
comment
У меня есть отдельные методы AuthService и AuthService.Nav, потому что у меня была проблема с циклической ссылкой Ionic в моих представлениях (а также для более чистого и расширяемого кода). Я попробую еще раз в качестве последнего решения. Для логического значения это не работает, потому что для входа в систему есть вызов Http и модальный вызов (требующий взаимодействия с пользователем для ввода его учетных данных). Так что там нужен промис, но я не смог реализовать его в методе Auth.service. - person user666; 15.07.2017