Fairly new to Angular, and struggling with Promises, Observables and async/await.
However, this doesn't seem to work. I have a feeling this has something to do with how Observables/subscribe works, but I am unable to solve it.
Code snippet:
initPage() {
fetchCurrentUserDetails().then((user) => { //tasks dependent on current user
//task 1
//task 2
});
}
fetchCurrentUserDetails(): Promise<any> {
return Promise.resolve((async () => {
let currentUser = this.global.getUser();// check if user is defined already
let userId: string = sessionStorage.getItem('userid');
if (currentUser == undefined) {
let initProfile = new Promise(resolve => resolve(this.fetchDetailsFromDB(userId)));
const profile: any = await initProfile; //Waits, but returns before the Observable comes back
let user = new User();
// initialize user with the fetched values
user.id = profile.id; // Undefined, since value not returned yet
user.name = profile.user_name; // Undefined, since value not returned yet
// Set this user in a global variable
this.global.setUser(user);
}
return this.global.getUser();
})());
}
fetchDetailsFromDB(userId: string) {
//callProfileService has nothing but the http.get statement
this.callProfileService(userId).subscribe((response) => {
let profile = response.body.response.data.user;
return profile;
});
}
Edit: adding how I tried with toPromise:
fetchDetailsFromDB(userId: string) {
this.callUserProfileService(userId).toPromise().then((response) => {
let profile = response.body.response.data.user;
return profile;
});
Is this the right way to do this? If so, how to make the await wait for the Observable to return?
Indeed, you need the toPromise() method, but don't forget to return that promise (the return in the callback is not enough -- the function fetchDetailsFromDB needs to return a promise).
On the rest of your code: it is an antipattern to use Promise.resolve and new Promise like that: as a rule of thumb, don't create a new promise with either of these when you already have a promise to work with (e.g. from an API function call).
So here is how you could do it with async methods:
async fetchCurrentUserDetails(): Promise<any> {
//^^^^
let currentUser = this.global.getUser();
if (currentUser == undefined) {
const userId: string = sessionStorage.getItem('userid');
const profile: any = await this.fetchDetailsFromDB(userId);
currentUser = new User();
currentUser.id = profile.id;
currentUser.name = profile.user_name;
this.global.setUser(currentUser);
}
return currentUser;
}
async fetchDetailsFromDB(userId: string): Promise<any> {
const response = await this.callUserProfileService(userId).toPromise();
return response.body.response.data.user;
};
you can use callback
initPage() {
fetchCurrentUserDetails((user) => {
//task 1
//task 2
});
}
fetchCurrentUserDetails(callback) {
const currentUser = this.global.getUser();
if (!currentUser) {
const userId: string = sessionStorage.getItem('userid');
return this.callProfileService(userId).subscribe((response) => {
const profile = response.body.response.data.user;
let user = new User();
user.id = profile.id;
user.name = profile.user_name;
this.global.setUser(user);
return callback(user);
});
} else {
return callback(currentUser);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With