2016-12-23 4 views
4

Я рассмотрел ряд ресурсов, включая this, this и this, но я не смог добиться желаемого результата.Angular2 - Невозможно прочитать свойство «подписаться» неопределенного во вложенном вызове

Все, что я пытаюсь сделать, это проверить подлинность пользователя (с помощью firebase), а затем один раз аутентификацию, загрузите свой профиль и сохранить его в переменной userProfile перед загрузкой на следующую страницу Приборная панель:

Мой сервис для входа в аккаунт :

public signinUser(user: User) { 
    this.af.auth.login({ 
     email: user.email, 
     password: user.password 
    }, 
     { 
      provider: AuthProviders.Password, 
      method: AuthMethods.Password 
     } 

    ) 
     .then(    
     success => { 
      console.log('Authenticated'); 
      this.getProfile().subscribe(// PROBLEM is here 
       profile => { 
        console.log(profile); 
        console.log('Profile Loaded'); 
        this.router.navigate(['/dashboard']); 
       } 
      )    
     } 
     ) 
     .catch(function (error) { 
      ... 
      console.log('ERROR SIGNING USER IN'); 
     } 

Мой getProfile() метод:

public getProfile(): Observable<any> {    
     return this.af.database.object('/profiles/' + this.user.uid) 
     .flatMap(
      profile => { 
       console.log('inside success'); 
       console.log(profile); 
       this.userProfile = <User>profile;      
       console.log('getProfile has completed');  
       return profile; 
      }, 
      error => { 
       console.log(error) 
      }); 

Это как часть журнала выглядит:

Authenticated 
auth.service.ts:104 ERROR SIGNING USER IN 
auth.service.ts:105 TypeError: Cannot read property 'subscribe' of undefined 
at auth.service.ts:91 
at ZoneDelegate.invoke (zone.js:232) 
at Object.onInvoke (ng_zone.js:238) 
at ZoneDelegate.invoke (zone.js:231) 
at Zone.run (zone.js:114) 
at zone.js:502 
at ZoneDelegate.invokeTask (zone.js:265) 
at Object.onInvokeTask (ng_zone.js:229) 
at ZoneDelegate.invokeTask (zone.js:264) 
at Zone.runTask (zone.js:154) 
auth.service.ts:106 Cannot read property 'subscribe' of undefined 
auth.service.ts:184 inside success 
auth.service.ts:185 Object {confirmPassword: "123123", email: "[email protected]", github: "aaa" name: "a", password: "123123"…} 
auth.service.ts:188 
getProfile has completed() 
auth.service.ts:185 

Я вижу, что методы индивидуально работают по назначению. Пользователь аутентифицируется, и профиль загружается (отображается в журнале). Проблема заключается в событии подписки по причинам, которые я не знаю.

ответ

3

Хорошо это странно, но я перезагрузил Webpack и, кажется, вылечили проблему.

Вот как выглядит код и правильно аутентификации через обещание, а затем в случае успеха он загружает профиль, который затем загружает следующую страницу:

Мой signinUser метод:

public signinUser(user: User) { 
    this.af.auth.login({ 
     email: user.email, 
     password: user.password 
    }, 
     { 
      provider: AuthProviders.Password, 
      method: AuthMethods.Password 
     } 

    ) 
     .then(    
     success => { 
      console.log('Authenticated'); 
      this.getProfile().subscribe(
       profile => { 
        this.router.navigate(['/dashboard']); 
       }, 
       error => console.log(error) 
      ) 

И мой getProfile метод:

public getProfile(): Observable<User> {   
     return this.af.database.object('/profiles/' + this.user.uid) 
     .map(    
      profile => { 
       console.log('inside success'); 
       console.log(profile); 
       this.userProfile = <User>profile;      
       console.log(this.userProfile);   
       return profile; 
      }, 
      error => { 
       console.log(error) 
      }); 
} 

стеком вызовов:

  1. Пользователь аутентифицируется
  2. Подписаться на getProfile и ждать способа закончить ...
    1. GetProfile() метод выполняет
    2. Профиль устанавливается
  3. Page перенаправляется
4

Я думаю, проблема в том, что getProfile действительно не возвращает Observable.

Вы используете flatMap, чтобы вы могли привязать наблюдаемую последовательность и вернуть профиль в качестве наблюдаемого. Но для того, чтобы это сработало, ваш обратный вызов внутри flatMap должен вернуть обещание или наблюдаемое (как я узнал от this answer). В противном случае цепь наблюдаемых нарушена.

Так что вы, вероятно, нужно сделать что-то вроде:

public getProfile(): Observable<any> {    
     return this.af.database.object('/profiles/' + this.user.uid) 
     .flatMap(
      profile => { 
       console.log('inside success'); 
       console.log(profile); 
       this.userProfile = <User>profile;      
       console.log('getProfile has completed');  
       return Promise.resolve(profile);//<-- this is what needs to be changed 
      }, 
      error => { 
       console.log(error) 
      }); 
+1

Thanks для ответа.Я закончил делать некоторые незначительные изменения и перезапустил 'webpack', и это странно решило мою проблему. Это была также моя мысль о том, что цепочечная последовательность не возвращала наблюдаемую, следовательно, ошибку. +1 как спасибо, и я думаю, что это будет полезный ответ другому! – gudthing

Смежные вопросы