How to make an observer to return as observable?

To benefit others, here's what I ended up writing and it seems to work well.

import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';

import { Observable } from 'rxjs/Observable';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { FirebaseService } from '../shared/firebase.service';


@Injectable()
export class AuthGuard implements CanActivate {

    loggedInSubject: ReplaySubject<any>;

    constructor(private firebase: FirebaseService, private router: Router) {
        this.loggedInSubject = new ReplaySubject(1);
        this.firebase.auth.onAuthStateChanged(this.loggedInSubject);
    }

    canActivate(): Observable<boolean> {
        return this.loggedInSubject.map(user => {
            if (!user) {
                this.router.navigate(['/login']);
            }
            console.log('Authenticated?', !!user);
            return !!user;
        }).take(1);
    }

}

Since onAuthStateChanged takes an observer as input, and returns the teardown function, we can simply wrap it with:

Rx.Observable.create(obs => firebase.auth().onAuthStateChanged(obs))

Actually for strange reasons this might not work, and we can do:

var onAuthStateChanged$ = Rx.Observable.create(obs => {
  return firebase.auth().onAuthStateChanged(
    user => obs.next(user),
    err => obs.error(err),
    () => obs.complete());
})

Now if you are unfamiliar with the Observable.create function, let me explain: create takes a onSubscribe function that hands in an observer and returns the teardown function. Doesnt that sounds very familiar with now onAuthStateChanged is build up? You hand in nextOrObserver and it returns the teardown!

(Now for strange reasons nextOrObserver did not accept an observer for me, so i switched to giving it a next function instead. Hench the code above.)

With the onAuthStateChanged$ set up, we can transform the stream using operators. All operators do is transform one observable into another, and RxJs has several dozen of these. In your case, it might look like this:

canActivate(): Observable<boolean> {
  onAuthStateChanged$
    .do(user => {if (!user) { this.router.navigate(['/login']); } })
    .map(user => !!user)
    .do(user => console.log('Authenticated?', user))
}