Return Observable<boolean> from service method after two subscriptions resolve
Solution 1
As noticed from other answer by @user184994, forkJoin
won't work in this case. Instead you can use combineLatest
, and then very similarily like @user184994 have otherwise implemented the service code:
isProfileOwner(): Observable<boolean> {
return Observable.combineLatest(this.currentUser, this.profileId$)
.map(results => {
let user = results[0];
let profile = results[1];
return (user.username === profile)
});
}
DEMO
Solution 2
This can be achieved through Subject
import { Subject } from 'rxjs';
public isProfileOwner(): Observable<boolean> {
var subject = new Subject<boolean>();
this.currentUser.subscribe(user => {
this.profileId$.subscribe(
profile => {
console.log(profile + ' ' + user.username); // match!
if (profile === user.username) {
subject.next(true);
} else {
subject.next(false);
}
}
)
})
return subject.asObservable();
}
Solution 3
I would personally suggest using forkJoin
, to wait for the observables, and flatMap to convert to an Observable<boolean>
return Observable.forkJoin(this.currentUser, this.profileId$).flatMap(
results => {
user = results[0];
profile = results[1];
return Observable.of(profile === user.username)
}
);
Comments
-
Ben Racicot almost 2 years
I'm trying to setup a simple way to compare the current username with a profile's username within an Angular service.
Obviously the profile username and the user's username must resolve before I can compare them so how do I return a boolean observable so that I can subscribe to this comparison within components?
This is where I'm at:
public profileId = new Subject<string>; // Observable string source updated from a profile.component (when the URL displays the profile's username) public profileId$ = this.profileId.asObservable(); public currentUser = this.principal.asObservable().distinctUntilChanged(); public isProfileOwner(): Observable<boolean> { // A function whose declared type is neither 'void' nor 'any' must return a value. this.currentUser.subscribe(user => { this.profileId$.subscribe( profile => { console.log(profile + ' ' + user.username); // match! if (profile === user.username) { return Observable.of(true); } else { return Observable.of(false); } } ) }) }
This seems to be the way other SO answers explain to do it but I'm getting
[ts] A function whose declared type is neither 'void' nor 'any' must return a value.
I'd like to subscribe to test within components.
this.authService.isProfileOwner().subscribe( data => { console.log(data); // should be boolean } )
-
Ben Racicot over 6 yearsgreat answer. Can explain how I should be subscribing to this boolean? (getting blank results)
-
user184994 over 6 yearsWhat do you mean by "blank results"?
-
Ben Racicot over 6 yearsI've updated the question to show my subscribe code. logging the result shows nothing.
-
user184994 over 6 yearsAs in, the log message is never printed?
-
Ben Racicot over 6 yearsYes, nothing is printed.
-
David Bulté over 6 yearsNice. But I think you can use map() iso flatmap()?
-
Ben Racicot over 6 years@DavidBulté awesome. Care to write up an answer? Having trouble rounding third on this.
-
Ben Racicot over 6 years@user184994 turns out
forkJoin
only works on raw Observable types.asObservable
,Subject
, etc will not work. -
Ben Racicot over 6 yearsthis is awesome, I've updated the question! I noticed that it doesn't work for me because my initial
profileId
is aSubject
source. I need this to be a subject (I think) so that profile.component can update it with the actual profile username. then becomes a stream with:profileId$ = this.profileId.asObservable();
-
AT82 over 6 yearsWell the difference between a Subject and a BehaviorSubject is basically that Subject requires
next
for subscription to fire. Not knowing your complete use case, but I don't see why you couldn't have it as an BehaviorSubject with initial value ofnull
or something and then do anull
check? Is that a possibility for you to do? -
Ben Racicot over 6 yearsThank you for patience, I was updating the BehaviorSubject wrong. Great answer to a complex question.
-
AT82 over 6 yearsNo problem, glad I could help! user184994 did a good job as well, just needed some minor tweaks to make it work, so glad we got you a solution! :)