How to show Auth0 Lock in an inline page container when using Angular?

1.2k views Asked by At

I am using Auth0 Lock to authenticate users and I'm trying to have the Lock widget not as popup but embedded in the page itself.

I tried using the container option and calling the lock.show() method from a script in the page I want it to load but it doesn't. Only if I call the lock.show() method from inside a function within ng-click does it shows the widget.

Initializing the Lock widget:

lockProvider.init({
        clientID: 'XXX',
        domain: 'YYY.auth0.com',
        options: {
            allowSignUp: false,
            container: 'hiw-login-container',
            auth: {
                responseType: 'token',
                params: {
                    scope: 'openid email'
                }
            },
            allowedConnections: ['Username-Password-Authentication']
        }
    });

The view:

 <div ng-if="!isAuthenticated" >
   <script>
       lock.show();
    </script>
    <md-content>
        <div id="hiw-login-container" style="width: 320px; margin: 40px auto; padding: 10px; border-style: dashed; border-width: 1px; box-sizing: border-box;">
             embedded area
         </div>
     </md-content>
 </div>

Calling lock.show from ng-click:

<md-button class="md-warn md-raised"
           aria-label="Login"
           ng-click="toolbar.authService.login()"
           ng-if="!isAuthenticated">
  Login
</md-button>

function login() {
    lock.show();
}

I can't upload pictures so here are links to the results shown when running the app:

  1. Initial state - before pressing anything (HomePage before pressing the login button)
  2. After pressing the login button (HomePage after pressing login button)

Why doesn't it show the widget from the start?

1

There are 1 answers

4
João Angelo On BEST ANSWER

You're using Angular so any Javascript code that is dependent of its rendering pipeline because it uses HTML elements that are managed by Angular itself need to play by those rules.

When you call it from ng-click Angular already did its thing and Lock will correctly find the target element and display correctly.

When you try to call lock.show from an inline script you can't guarantee that Angular already completed processing and things won't work.

You need to call lock.show from code that is Angular aware; you could consider a few things:

function YourController($scope) {
   $scope.$on('$viewContentLoaded', lock.show);
}

or

angular.element(lock.show);

or even consider going for a directive that understands when Angular has made the HTML element available and calls lock.show.