1

I'm creating an Angular 2 SPA for learning purposes and integrating Auth0 for handeling the authentication. I have an auth.service.ts that is going to be called from difference places in my application, for example in the top-navbar to logout and on the auth-page to handle logins and registrations.

When trying to place the Auth0 container in a div by setting the container option I get the following error: Can't find element with id auth-container

How can I let the auth.service know how/where to look for the auth-container div? Placing all the logic inside the auth.component.ts is assumably not an option because the auth.service will be used for other functionality in other places where the lock variable is also used.

auth.service.ts

import { Injectable }      from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt';
import { myConfig }        from './auth.config';

declare var Auth0Lock: any;
var options = { container: 'auth-container' };

@Injectable()
export class Auth {

    lock = new Auth0Lock(myConfig.clientID, myConfig.domain, options);

    constructor() {
        this.lock.on('authenticated', (authResult) => {
            localStorage.setItem('id_token', authResult.idToken);
        });
    }

    public authenticated() {
        return tokenNotExpired();
    };

    public logout() {
        localStorage.removeItem('id_token');
    };
}

auth.component.ts

constructor(public auth: Auth) {
    auth.lock.show();
}

auth.component.html

 <div id="auth-container"></div>
Sam
  • 1,303
  • 3
  • 23
  • 41

2 Answers2

1

Well they did not make your life easy but by mistake I made it work.

Try this:

auth.component.ts

ngOnInit() {
    this.auth.login()
  }

Delete this from your constructor

auth.lock.show();
Avram Virgil
  • 1,170
  • 11
  • 22
0

The auth.service is not a container, it's a service that provides a popup when the login function is invoked.

So, to reuse it wherever you like, you need to inject the auth service into the component where you want to call the auth service from. Then, you just call the method. For example, here is the html for my Start component. You can see that the click event for the signin button is bound to the "submitLogin()" method of the component (the Start component):

<div class="splash-back" *ngIf="!authService.authenticated()">
  <div id="splash">

    <div id="logo"><span class="silver">GCO</span>TeamKeeper
      <p class="silver tagline">The other teams could make trouble for us if they win.</p>
      <p class="silver attribution">~ Yogi Berra</p></div>
    <div class="call">

      <br>

      <button class="btn-sign-in" (click) = "submitLogin()">Sign up or Log in</button>
    </div>
    <!--<mtm-authentication></mtm-authentication>-->
  </div>
</div>

And here is the start component code (note the injection of the authentication service in the constructor):

@Component({
  selector: 'tk-start',
  templateUrl: './start.component.html',
  styleUrls: ['./start.component.css']
})
export class StartComponent implements OnInit {

  constructor(private authService: UserAuthenticationService) { }

  ngOnInit() {
  }

  submitLogin(){
    this.authService.login();
  }
}

And to make this example complete, here is my auth service code:

import {Injectable} from "@angular/core";

import { tkConfig } from './user-authentication.config';
import {Router} from "@angular/router";
import {tokenNotExpired} from "angular2-jwt";


let Auth0Lock = require('auth0-lock').default;

@Injectable()
export class UserAuthenticationService {

  // Configure Auth0
  userProfile: Object;

  lock = new Auth0Lock (tkConfig.clientID, tkConfig.domain, {
      avatar: null,
      theme: {
        primaryColor: "#69BE28",
        foregroundColor: "#000000"
      },
      languageDictionary: {
        title: "GCO TeamKeeper"
      }
    }
  );

  constructor(
    private router: Router) {

    this.userProfile = JSON.parse(localStorage.getItem('profile'));

    // Add callback for lock `authenticated` event
    this.lock.on('authenticated',  (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);

      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          alert(error);
          return;
        }

        profile.user_metadata = profile.user_metadata || {};
        localStorage.setItem('profile', JSON.stringify(profile));

        this.userProfile = profile;

        this.router.navigate(['/organization']);

      });
    })
  }

  public login() {
    // Call the show method to display the widget.
    this.lock.show();
  };

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

  public logout() {
    // Remove token from localStorage
    localStorage.removeItem('id_token');
    localStorage.removeItem('profile');
    this.userProfile = undefined;

    this.router.navigate(['/start']);
  };
}
glitchbane
  • 327
  • 5
  • 11