Lock: [v10] Auth0Lock not compatible with RxJS

Created on 8 Aug 2016  路  12Comments  路  Source: auth0/lock

Instead of using native handler 'this.lock.on('event', result)' I would like to create an Observable from that event like below:

import Auth0Lock from 'auth0-lock';

import {
  Effect,
  StateUpdates
} from '@ngrx/effects';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
import { AuthActions } from './auth.actions';
import { tokenNotExpired } from 'angular2-jwt';
import { UserActions } from '../user/user.actions';


@Injectable()
export class AuthEffects {
  private lockOptions: Object = {
    mustAcceptTerms:   true,
    socialButtonStyle: "big",
    autofocus: true,
    auth: {
      redirect: false,
      responseType: 'token'
    },
    theme: {
      logo: "https://logo.png",
      primaryColor: "#ec4889"
    }
  };
  private lock = new Auth0Lock(
    'abc',
    'def',
    this.lockOptions
  );

  constructor(private updates$: StateUpdates) {}

  @Effect() public authenticated$ = new Observable
    .fromEvent(this.lock, 'authenticated')
    .do((authResult: LockAuthResult) => localStorage.setItem('id_token', authResult.idToken))
    .map((authResult: LockAuthResult) => UserActions.getProfile({token: authResult.idToken, lock: this.lock}));


  @Effect() public login$ = new Observable
    .of(AuthActions.login());


  @Effect() public performLogin$ = this.updates$
    .whenAction(AuthActions.LOGIN)
    .filter(() => !tokenNotExpired())
    .do(this.lock.show())  // must be commented out because many of functionality rely on "authenticated" event to be fired first
    .map(() => AuthActions.lockDisplayed());


  @Effect() public logout$ = this.updates$
    .whenAction(AuthActions.LOGOUT)
    .do(() => localStorage.removeItem('id_token'))
    .do(() => this.lock.show())
    .map(() => UserActions.clearProfile());
}

Unfortunately no event is received by RxJS, which is strange since Auth0Lock is an instance of nodejs EventEmitter, which is compatible with Observable.fromEvent.

Also I would like to handle profile the same way, but no info is provided what returns function 'lock.getProfile'. Is it a Promise or smth else!?!?!?

I want to use that function like below:

new Observable.fromPromise(this.lock.getProfile(token))
  .map((error, profile) => {
    if (error) {
      return UserActions.errorGettingProfile(error)
    } else {
      return UserActions.loadProfile(profile)
    }
  })

Most helpful comment

@dszmaj so, just an FYI. I got the following to work:

@Effect()
    authenticated$ = Observable
        .fromEvent(this.authService.authLock, 'authenticated')
        .do((authResult: any) => {
            localStorage.setItem('id_token', authResult.idToken);
        })
        .map(()=>new auth.LoginSuccessAction({}));

and also got an Observable working from the getProfile call like so:

getProfile(idToken: string): Observable<any>{
        return new Observable(observer => {
            this.lock.getProfile(idToken, (err, profile) => {
            if (err) {
                observer.error(err);
            }
            else {
                console.log(profile);
                observer.next(profile);
                observer.complete();
            }
            });
        });
    }

good luck!

All 12 comments

nvm about 'lock.getProfile' I found this:
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-bindCallback

i didnt receive answer! why close?

I thought you said "nvm". Is this still an issue then?

yes, just the first part, somehow i cant make observale from these events

+1

+1,000,000

@dszmaj what did you end up doing for a fix?

plain ugly documentation way, without observables

inside callbacks you can dispatch events to store, and make this reactive

@woloski please open this issue again since this is still not resolved

@dszmaj so, just an FYI. I got the following to work:

@Effect()
    authenticated$ = Observable
        .fromEvent(this.authService.authLock, 'authenticated')
        .do((authResult: any) => {
            localStorage.setItem('id_token', authResult.idToken);
        })
        .map(()=>new auth.LoginSuccessAction({}));

and also got an Observable working from the getProfile call like so:

getProfile(idToken: string): Observable<any>{
        return new Observable(observer => {
            this.lock.getProfile(idToken, (err, profile) => {
            if (err) {
                observer.error(err);
            }
            else {
                console.log(profile);
                observer.next(profile);
                observer.complete();
            }
            });
        });
    }

good luck!

@photostu thank you for your code, was just wondering how you handle login fails?

@woloski I believe this issue is very useful and meaningful. Please re-open it, thanks!

@photostu Where do you put that code, where do you define the getProfile function ? and where do you subscribe?

Was this page helpful?
0 / 5 - 0 ratings