Auth0.js: Cannot read property 'getStoredTransaction' of undefined

Created on 19 Jul 2017  路  6Comments  路  Source: auth0/auth0.js

I'm using binding the parseHash function to RxJS and Redux-Observable and I'm getting the following error (I'm pretty sure its Auth0.js related but I could be wrong):

Cannot read property 'getStoredTransaction' of undefine

Here is my function call:

export const parseLogin = (action$, store) =>
  action$.ofType(actionTypes.parseLogin)
    .mergeMap(action => {
      const webAuth = store.getState().app.webAuth
      if (typeof webAuth !== 'undefined') {

        const parse = Observable.bindCallback(webAuth.parseHash)
        return parse(window.location.hash)
          .map((err, authResult) => {

            console.log(authResult.accessToken)

          })
          .catch(e => {
            console.log(e)
          })

      }
    })

Most helpful comment

Hey there everyone!

It turns out you can use bindNodeCallback in RxJS to create an observable from parseHash. The difference between bindNodeCallback and bindCallback is that it is expecting that extra error parameter in the callback. You can read more about it in the RxJS docs.

To use bindNodeCallback to create an observable from parseHash, you need to also bind the Auth0 client to it. Here it is in Angular & TypeScript:

// auth.service.ts
private _Auth0 = new auth0.WebAuth({
  clientID: 'XXXX',
  domain: 'domain.auth0.com',
  responseType: 'token id_token',
  audience: 'https://your_api/',
  redirectUri: `${location.protocol}//${location.host}/callback`,
  scope: 'openid profile email'
});

// Create observable of Auth0 parseHash method to gather auth results
parseHash$ = bindNodeCallback(this._Auth0.parseHash.bind(this._Auth0));

Note that when you subscribe to an observable created by bindNodeCallback, you call it as a function in order to pass in any arguments. for parseHash it would look like this:

this.parseHash().subscribe(authResult => {
 // Store the token, clear the hash, etc.
});

In plain old JavaScript, you should be able to bind the const that you created. You can see a similar example of this with bindNodeCallback and redis at this issue.

The same pattern will work with checkSession, just beware that you need to pass in an empty object to the checkSession observable subscription for it to work (checkSession$({}).subscribe()).

Hope that helps!

All 6 comments

can you try calling parseHash without all of that and see if it works? parseHash is very important for auth0.js and Lock. I'm pretty sure we'd have been flooded with issues if it wasn't working 馃槄

I also tried to use the rxjs bindCallback method but it did not work neither.
It's because when the parseHash method is called, it's not bound and do not have access to this (which is undefined).

@luisrudge parseHash was working perfectly before hand. @FabienDehopre did you come up with a workaround for this?

Ok. Since this is not auth0.js related, I'll close the issue. Thanks for the update @NathHorrigan 馃帀

@NathHorrigan You wrap the call to parseHash inside an observer:

const webAuth = new auth0.WebAuth({
  clientID: 'XXXX',
  domain: 'domain.auth0.com',
  responseType: 'token id_token',
  audience: 'https://your_api/',
  redirectUri: `${location.protocol}//${location.host}/callback`,
  scope: 'openid profile email'
});
///////////////////////////////////////////
Observable.create(observer => {
  webAuth.parseHash((err, authResult) => {
    if (err) {
      observer.error(err);
    }
    else if (authResult && authResult.idToken && authResult.accessToken) {
      observer.next(authResult);
    }

    observer.complete();
  });
});

Hey there everyone!

It turns out you can use bindNodeCallback in RxJS to create an observable from parseHash. The difference between bindNodeCallback and bindCallback is that it is expecting that extra error parameter in the callback. You can read more about it in the RxJS docs.

To use bindNodeCallback to create an observable from parseHash, you need to also bind the Auth0 client to it. Here it is in Angular & TypeScript:

// auth.service.ts
private _Auth0 = new auth0.WebAuth({
  clientID: 'XXXX',
  domain: 'domain.auth0.com',
  responseType: 'token id_token',
  audience: 'https://your_api/',
  redirectUri: `${location.protocol}//${location.host}/callback`,
  scope: 'openid profile email'
});

// Create observable of Auth0 parseHash method to gather auth results
parseHash$ = bindNodeCallback(this._Auth0.parseHash.bind(this._Auth0));

Note that when you subscribe to an observable created by bindNodeCallback, you call it as a function in order to pass in any arguments. for parseHash it would look like this:

this.parseHash().subscribe(authResult => {
 // Store the token, clear the hash, etc.
});

In plain old JavaScript, you should be able to bind the const that you created. You can see a similar example of this with bindNodeCallback and redis at this issue.

The same pattern will work with checkSession, just beware that you need to pass in an empty object to the checkSession observable subscription for it to work (checkSession$({}).subscribe()).

Hope that helps!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andreasvirkus picture andreasvirkus  路  7Comments

beno picture beno  路  3Comments

StefH picture StefH  路  5Comments

kmaida picture kmaida  路  7Comments

jorgeucano picture jorgeucano  路  6Comments