在我开始我的问题之前,我想让你知道我已经做了一个很大的研究,但我找不到解决方案(解释)为什么会出现这个错误。
另请注意,我是 Angular 的新手,我刚刚开始学习它是如何工作的。
所以,我遇到的问题是我在这个问题的标题中输入的内容。
我尝试做的是基于我在 Udemy 上购买的课程,使用 Firebase 构建登录系统。
我使用的代码如下:
auth.service.ts
import {Injectable} from '@angular/core';
import * as firebase from 'firebase';
@Injectable ()
export class AuthService {
token: string;
// ...
singInUser ( email: string, password: string ) {
// login process here ...
}
// Responsible to retrieve the authenticated user token
getToken () {
return firebase
.auth ()
.currentUser
.getIdToken ();
}
}
数据存储.service.ts
// ... Dependencies here
@Injectable ()
export class DataStorageService {
private recipeEndPoint: string = 'https://my-unique-id.firebaseio.com/recipes.json';
private recipeSubscription: Observable<any> = new Observable();
constructor ( private http: Http,
private recipes: RecipeService,
private authService: AuthService ) {}
// other functionality ...
getRecipes () {
const token = this.authService.getToken ();
token.then (
( token: string ) => {
this.recipeSubscription = this.http.get ( this.recipeEndPoint + '?auth=' + token ).map (
( data: Response ) => {
return data.json ();
}
);
// THIS PARTICULAR CODE WORKS AS EXPECTED
// WITH NO ISSUES
this.recipeSubscription.subscribe (
( data: Response ) => {
console.log ( 'Data response: ', data );
},
( error ) => {
console.log ( 'Error: ' + error );
}
)
}
);
// This is supposed to return an Observable to the caller
return this.recipeSubscription;
}
}
header.component.ts
// Dependencies here ...
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor(private dataStorage: DataStorageService, private recipeService: RecipeService) { }
// Other Code Here ...
onFetchData() {
let recipeSubscription = this.dataStorage.getRecipes();
// THIS RETURNS TRUE
console.log(recipeSubscription instanceof Observable);
// THIS LINE THEN RETURNS THE MESSAGE:
// ERROR TypeError: Cannot read property 'subscribe' of undefined
recipeSubscription.subscribe();
// IF I COMMENT OUT THE PREVIOUS LINE
setTimeout(
() => {
// THIS RETURNS TRUE
console.log(recipeSubscription instanceof Observable);
},
500
);
setTimeout(
() => {
// AS WELL THIS ONE RETURNS TRUE
console.log(recipeSubscription instanceof Observable);
},
1000
);
setTimeout(
() => {
// AS WELL THIS ONE RETURNS TRUE
console.log(recipeSubscription instanceof Observable);
},
1500
);
}
}
所以,不幸的是,我看不出这段代码有什么问题。谁能发现我做错了什么?
注意: 我删除了部分代码只是为了使片段更具可读性。如果您需要任何其他部分,请随时问我,我会在这里提供。
更新#1
这就是它的样子 header.component.html
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">Logo Here</div>
<div class="navbar-default">
<ul class="nav navbar-nav">
<!-- Left Navigation Options -->
</ul>
<ul class="nav navbar-nav navbar-right">
<!-- Right Navigation Options -->
<li class="dropdown" appDropdown>
<a routerLink="/" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>
<a style="cursor: pointer;" (click)="onSaveData()">Save Data</a>
</li>
<li>
<!-- Here is where I call the onFetchData method -->
<a style="cursor: pointer;" (click)="onFetchData()">Fetch Data</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
原文由 KodeFor.Me 发布,翻译遵循 CC BY-SA 4.0 许可协议
问题似乎是您的代码执行的顺序,更具体地说是
getRecipes()
方法:解决方案是您的
getRecipes ()
方法不应该订阅。它应该 返回一个 Promise 或一个 Observable 。像这样的东西:
然后,
HeaderComponent
中的调用代码变成:几点说明:
getRecipes()
。总是在最后一刻订阅。您可以多次订阅同一个 observable,但请注意,每个订阅都会重新执行 observable(在 http 请求的情况下,这意味着您多次运行请求;不理想……)。recipeSubscription
不是一个好主意,因为它包含Observable
,而不是Subscription
。订阅是subscribe()
返回的内容。换句话说:const subscription = observable.subscribe()
。