Describe the bug
After login Angular 7 app this.Auth1.authStateChange$.subscribe is not showing state change. I need to refresh the page manually to reflect user ids.
What AWS Services are you utilizing? - Amazon Cognito Hosted UI
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
no
Desktop (please complete the following information):
Smartphone (please complete the following information):
-N/A
Additional context
Add any other context about the problem here.
Sample code
import { Component, OnInit, OnDestroy } from '@angular/core';
import { AmplifyService } from 'aws-amplify-angular';
import {SlimLoadingBarService} from 'ng2-slim-loading-bar';
import * as $ from 'jquery';
import { NavigationCancel,
Event,
NavigationEnd,
NavigationError,
NavigationStart,
Router } from '@angular/router';
import { Gtag } from 'angular-gtag';
import { GlobalVariable } from '../app.global';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
title = 'Study Buddy';
signedIn: boolean;
isAdmin: boolean;
user: any;
role: any;
greeting: string;
useremail: any;
Auth1: AmplifyService;
constructor(private loadingBar: SlimLoadingBarService, private amplifyService: AmplifyService,
private _router: Router, gtag: Gtag) {
this.loadingBar.start();
this.isAdmin = false;
this.Auth1 = amplifyService;
// this.Auth1.auth().currentAuthenticatedUser()
// .then(data => console.log('data' + JSON.stringify(data)))
// .catch(err => console.log(err));
this.Auth1.auth().currentAuthenticatedUser({
bypassCache: true }).then(user => console.log('data' + JSON.stringify(user.attributes.email)))
.catch(err => console.log(err));
// gtag.event('init', { event_label: 'App Init'});
console.log('App Component');
this.Auth1.authStateChange$
.subscribe(authState => {
console.log('Auth state changed.='+authState.state);
this.signedIn = authState.state === 'signedIn';
if (!authState.user) {
localStorage.clear();
this.user = null;
this.useremail = null;
} else {
this.user = authState.user;
this.useremail = this.user.attributes.email;
console.log('Greeting=' + this.greeting + 'email=' + this.useremail);
// Set item:
if ( this.useremail == '[email protected]' ) //Set Admin
{
this.role = 'admin';
this.isAdmin = true;
}
else
{
this.role = 'user';
this.isAdmin = false;
}
let myObj = { name: this.user , email: this.useremail, role: this.role };
localStorage.removeItem('user');
localStorage.setItem('user', JSON.stringify(myObj));
//let item = JSON.parse(localStorage.getItem(key)); //in ngOnInit()
}
this.loadingBar.complete();
});
this._router.events.subscribe((event: Event) => {
this.navigationInterceptor(event);
});
}
private navigationInterceptor(event: Event): void {
if (event instanceof NavigationStart) {
this.loadingBar.start();
}
if (event instanceof NavigationEnd) {
this.loadingBar.complete();
}
if (event instanceof NavigationCancel) {
this.loadingBar.stop();
}
if (event instanceof NavigationError) {
this.loadingBar.stop();
}
}
ngOnInit() {
//$('body').addClass('df');
console.log('oninit' + this.role );
}
ngOnDestroy() {
localStorage.removeItem('user'); // localStorage.clear();
}
onLoginClick() {
const URL = GlobalVariable.COGNITO_URL;
window.location.assign(URL);
}
}
You can turn on the debug mode to provide more info for us by setting window.LOG_LEVEL = 'DEBUG'; in your app.
Same issue, the AuthState raises a message on page load, but when using the authorization code grant using the Hosted UI it doesn't raise a message after the code exchange.
@manojknit @ADringer when using Cognito Hosted UI, you need to use the Hub class to listen on the auth events, please check the doc: https://aws-amplify.github.io/docs/js/authentication#oauth-and-hosted-ui
Although the sample code is written in React, but logic should be the same. Basically you need to listen on the auth event in the Hub class when the page is loaded.
Thank You. I used the following code.
import Amplify, { Auth, Hub } from 'aws-amplify';
Hub.listen("auth", ({ payload: { event, data } }) => {
switch (event) {
case "signIn":
this.Auth1.setAuthState({ state: 'signIn', user: data });
//console.log('hub data1=' + JSON.stringify(data));
console.log('hub email=' + JSON.stringify(JSON.parse(data.storage[data.userDataKey]).UserAttributes[2].Value));
this.Auth1.auth().currentUserInfo().then(user => {
console.log('Inside currentUserInfo email=' + JSON.stringify(user.attributes.email));
this.user = user.username; //user.attributes.email_verified
this.useremail = user.attributes.email;
this.signedIn = user.attributes.email_verified;
Most helpful comment
Thank You. I used the following code.
import Amplify, { Auth, Hub } from 'aws-amplify';
Hub.listen("auth", ({ payload: { event, data } }) => {
switch (event) {
case "signIn":
this.Auth1.setAuthState({ state: 'signIn', user: data });
//console.log('hub data1=' + JSON.stringify(data));
console.log('hub email=' + JSON.stringify(JSON.parse(data.storage[data.userDataKey]).UserAttributes[2].Value));