I'm currently working on an Angular 2 project with AngularFire2 and I'm trying to convert a FirebaseListObservable to a Promise. I know that it doesn't make much sense since Observables are more useful but this function will be part of another function where multiple promises are chained. And I'm not familiar with how to subscribe to Observables within a chain of promises... The function gets executed in the service, however it seems to not return anything. Basically, what I want to do is check in a Firebase list if an object with a certain name already exists and return either true or false.
constructor(private _af: AngularFire) { }
nameExists(name: string): Promise<boolean> {
return this._af.database.list('users')
.map(users => {
let exists = false;
users.forEach(user => {
if(user.name.toLowerCase() === name.toLowerCase()) {
console.log('Name already exists!');
exists = true;
}
});
return exists;
}).toPromise();
}
constructor(private _usersService: UsersService) { }
check(name) {
this._usersService.nameExists(name)
.then(bool => console.log(bool));
}
So the function gets executed and seems to work correctly as it prints to the console, when there's a match. However, console.log() in the component does not get executed. I guess the "then" part is never reached. On a separate note, is there a way to stop the forEach loop once a match is found?
Any help would be greatly appreciated as I couldn't find any answers at all to this.
The problem is that the toPromise
operator converts the observable to a promise that resolves to the observable's final value. That means the observable must complete before the promise resolves.
In AngularFire2, list and object observables don't complete; they re-emit whenever the database changes.
You can solve the problem using the first
operator, which takes the first emitted value and then completes the composed observable:
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
...
return this._af.database
.list('users')
.map(users => {
let exists = false;
users.forEach(user => {
if (user.name.toLowerCase() === name.toLowerCase()) {
console.log('Name already exists!');
exists = true;
}
});
return exists;
})
.first()
.toPromise();
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