Reputation: 1227
I've created a authentication service which components can subscribe to permission changes (login/logout/role change ,etc). In isAuthenticated function, I'm returning a subject. The problem is that I want to return the subject with a value (like Observable.of. For now, I'm using setTimeout.
@Injectable()
export class AuthenticationService {
constructor(private credentials: CredantialsStorageService,
private oauthService:OAuth2Service,
private secureHttp: SecureHttpService) {}
private isAuthenticatedSubject: Subject<boolean> = new Subject<boolean>();
login(email:string, password: string, remember?:boolean ): Observable<boolean> {
return this.oauthService.login(email, password)
.flatMap(() => this.getAndStoreUserCredantials())
.map((userCredantials: any) => {
this.isAuthenticatedSubject.next(true);
return true;
})
}
logout(): Observable<void> {
return this.secureHttp.post('/logout', null)
.finally(() => {
this.credentials.clear();
this.oauthService.clear();
this.isAuthenticatedSubject.next(false);
})
.map(() => null);
}
isAuthenticated(): Observable<boolean> {
setTimeout(() => { //Hack - find a way to change this
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
})
return this.isAuthenticatedSubject;
}
private getAndStoreUserCredantials() {
return this.secureHttp.get('/user/info')
.map((res:Response) => {
let userCredantials = res.json();
this.credentials.set(userCredantials);
return userCredantials;
})
}
}
Upvotes: 3
Views: 7388
Reputation: 96891
I think the easiest way to do this is using the startWith()
operator:
isAuthenticated(): Observable<boolean> {
return this.isAuthenticatedSubject.startWith(this.oauthService.isAuthenticated());
}
You could also use BehaviorSubject
or ReplaySubject
but these only repeat a value that went through them already. Maybe also have a look at this answer for more detailed description what's the difference: Does startWith() operator turns Observable into ReplaySubject(1)?.
Upvotes: 2
Reputation: 8468
You can return it as an Observable using .asObservable()
.
isAuthenticated(): Observable<boolean> {
setTimeout(() => { //Hack - find a way to change this
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
})
return this.isAuthenticatedSubject.asObservable();
}
If you want to however, add some delay for into your method, you could use Obersvable.delay()
, and then use .do()
operator:
isAuthenticated(): Observable<boolean> {
Observable
.delay(1000) //delay for 1000ms
.do(() => {
this.isAuthenticatedSubject.next(this.oauthService.isAuthenticated());
});
return this.isAuthenticatedSubject.asObservable();
}
Upvotes: 2
Reputation: 1228
If you'd like to set an initial value for the Subject
, you could use a BehaviorSubject
. The only difference is that you pass your initial value to BehaviorSubject
constructor.
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
const subject = new BehaviorSubject(42);
subject.subscribe((value) => console.log(value));
// 42
subject.next(84);
// 84
Upvotes: 1