Reputation: 6687
I have a method in a the class below:
export class SearchService {
userUID: string;
searchItems: any;
private searchesCollection: AngularFirestoreCollection;
constructor(
private db: AngularFirestore,
private afAuth: AngularFireAuth,
) {
}
getSearches() {
this.afAuth.authState.subscribe(user => {
this.userUID = user['uid'];
this.searchesCollection = this.db.collection(`users/${this.userUID}/searches`);
this.searchItems = this.searchesCollection.valueChanges().subscribe(data => {
console.log(data); // works
return data;
});
});
console.log(this.searchItems); // undefined
return this.searchItems; //undefined
}
}
My issue is with the return statement, it is returning undefined. The console.log(data) a few lines above it returns the value I want. I am wondering why I am getting undefined. It might be a scoping issue but I can't seem to figure it out. What am I overlooking?
Upvotes: 2
Views: 9397
Reputation: 12036
You are working with async programming you cannot pause the execution of the code and your subscription will be resolved in future but you cannot predict when. console.log()
outside the subscribe
is executed before your subscription is resolved that's why it's undefined
and console.log()
inside subscribe call back is invoked after the subscription is resolved.
Refer this for better understanding.
what you can do is You can store the value in a class property and access it in your template.
getSearches() {
this.afAuth.authState.subscribe(user => {
this.userUID = user['uid'];
this.searchesCollection = this.db.collection(`users/${this.userUID}/searches`);
this.searchesCollection.valueChanges().subscribe(data => {
console.log(data); // works
this.searchItems=data;
});
});
console.log(this.searchItems); // undefined
return this.searchItems; //undefined
}
HTML
{{searchItems?.//property}}
or you can use async pipe
AsyncPipe accepts as an argument an observable
or a promise, calls subscribe
or attaches a then handler, then waits for the asynchronous result before passing it through to the caller.
getSearches() {
this.afAuth.authState.subscribe(user => {
this.userUID = user['uid'];
this.searchesCollection = this.db.collection(`users/${this.userUID}/searches`);
this.searchItems=this.searchesCollection.valueChanges();
}
HTML
<ng-container *ngFor="let item of searchItems|async">
{{item?.//property}}
<ng-container>
Upvotes: 2
Reputation: 369
getSearches() {
this.afAuth.authState.subscribe(user => {
this.userUID = user['uid'];
this.searchesCollection = this.db.collection(`users/${this.userUID}/searches`);
this.searchItems = this.searchesCollection.valueChanges().subscribe(data => {
console.log(data); // works
return data;
});
});
console.log(this.searchItems); // undefined
return this.searchItems; //
there is an async call in this. Since you are returning the value before your call is resolved or comes back you will not have data in this.searchItems
since you are using a call to server or to db, use observable to take advantage of Angular's promise concept.
Upvotes: 1