Auth0 Home Blog Docs

Angular 2+ Custom Login - this.lock.parseHash is not a function error

spa
custom-login
angular2

#1

I am trying to implement a custom login in my angular 2 spa.

I used the official documentation as a guide and made sure to follow all the steps.

Angular2-jwt was successfully included in the project. I also made sure to call the handleAuthentication
method in the application’s root component.

Here is the auth.service.ts

import { Injectable }      from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt';
import { Router }          from '@angular/router';

// Avoid name not found warnings
let Auth0Lock = require('auth0-lock').default;

var options = {
   auth: {
     redirect: true,
     redirectUrl: "http://localhost:54435/home",
     responseType: "token id_token",
   },
  rememberLastLogin: false
};

@Injectable()
export class Auth {

  // Configure Auth0
  lock = new Auth0Lock('xxx', 'xxx', options);

  constructor(private router: Router) {
  }

  public handleAuthentication(): void {
    this.lock.parseHash({ _idTokenVerification: false }, (err, authResult) => {
      if (err) {
        alert(`Error: ${err.errorDescription}`)
      }
      if (authResult && authResult.accessToken && authResult.idToken) {
        window.location.hash = '';
        localStorage.setItem('access_token', authResult.accessToken);
        localStorage.setItem('id_token', authResult.idToken);
        this.router.navigate('/home']);
      }
    });
  }

  public login(username: string, password: string) {
    this.lock.redirect.loginWithCredentials({
      connection: 'Username-Password-Authentication',
      username,
      password
    }, err => {
      if (err) return alert(err.description);
    });
  }

  public authenticated() {
    // Check if there's an unexpired JWT
    // This searches for an item in localStorage with key == 'id_token'
    return tokenNotExpired('id_token');
  }

  public logout() {
    // Remove token from localStorage
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
  }

  private setUser(authResult) {
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('id_token', authResult.idToken);
  }
}

I noticed that someone had the same issue in this thread.
The answer from @jmangelo :

“That particular page seems to be referencing an incorrect code snippet version given that the parseHash function was available in a previous version of Lock, but not in version 10.”

Is the code in the documentation outdated or is the error in my code?

The versions I’m using:

“angular2-jwt”: “^0.2.3”,
“auth0-js”: “^8.6.0”,
“auth0-lock”: “^10.14.0”

I’m willing to provide any additional information.


#2

The custom login quickstart step uses Auth0.js instead of Auth0 Lock. I checked the step you linked and the code is correctly using Auth0.js, more specifically, you have:

declare var auth0: any;
//...
auth0 = new auth0.WebAuth({
    domain: '...',
    clientID: '...',
    // ...
  });
// ...
this.auth0.parseHash(...)
// ...
this.auth0.redirect.loginWithCredentials(...)

However, in your code you’re trying to use Auth0 Lock to call methods that are only available in Auth0.js.

The following is incorrect and explains the parseHash is not defined error:

lock = new Auth0Lock('xxx', 'xxx', options);
//...
this.lock.parseHash(...)
//...
this.lock.redirect.loginWithCredentials(...)

#3

Thank you for the answer.
The reason I made those changes was because if I used “declare var auth0: any;” i’d get “auth0 is not defined” error.

I fixed this by including Auth0.js in my program by adding: <script src="https://cdn.auth0.com/js/auth0/8.0/auth0.min.js"></script> and adding import * as auth0 from 'auth0-js'; in my auth.service.ts.

I now use the exact same auth.service.ts as provided in the mentioned documentation and I get through with no errors. However upon logging in I get a Post error.

I just made a seperate post describing my problem. https://community.auth0.com/questions/2466/angular-2-custom-login-post-404-not-found-on-login.


#4