I spent 3 days for this problem, I need your help
I have a 2 problems about google social login in my Angular project.
Keeping user logged in after refresh (i used Google OAuth2)
when first rendering, i can't see login button:(
I solved first proble according to this link, but i solved first proble according to this link, The second problem still haunts me.
I think my project has problem which oninit function complete after templete rendering.
This code is my component.ts file.
export class NavbarComponent implements OnInit {
log : boolean
test : any
googleAuth: any
auth2 : gapi.auth2.GoogleAuth
constructor(
private ref : ChangeDetectorRef,
private http: HttpClient) { }
async ngOnInit() {
gapi.load('auth2', () => {
gapi.auth2.init({
client_id: 'MY_CLIENT_ID',
scope : 'email',
})
.then((data) => {
this.auth2 = data;
this.googleAuth = gapi.auth2.getAuthInstance();
this.log = this.handleAuthChange();
this.googleAuth.isSignedIn.listen(this.handleAuthChange);
})
})
}
signIn = () => {
this.auth2.signIn()
};
signOut = () => {
this.auth2.signOut();
};
handleAuthChange = () => {
return this.googleAuth.isSignedIn.get();
}
I want to make a login function use onlu one button so, i wrote template code like this.
<nav class="navbar-container">
<a routerLink="/" class="main-icon-brand">
<img src="../../assets/image/icon.png" alt="logo image" id="icon-image">
</a>
<a routerLink="/tutorial" class="each-item">
<span>Tutorial</span>
</a>
<a routerLink="/making" class="each-item">
<span>Making</span>
</a>
<a routerLink="/search" class="each-item">
<span>Search</span>
</a>
<div id="navbar-space"></div>
<div>
<div *ngIf="log === false">
<button (click)="signIn()" mat-icon-button color="warn">
<mat-icon>account_circle</mat-icon>
</button>
</div>
<div *ngIf="log === true">
<button (click)="signOut()" mat-icon-button color="warn">
<mat-icon>face</mat-icon>
</button>
</div>
</div>
</nav>
umm... i think, this has two solution
I assume when you say that you can't see the login button when it is first rendering, you mean that it loads in with a delay.
It isn't because ngOnInit() is running out of order, it is because your ngOnInit creates a promise that doesn't get resolved until after some of the other lifecycles have completed. The code inside the then(...)
clause only runs once the promise has resolved. It takes time for the Google Api to do what you are asking it to do and so you have to code around that a bit to make your page load in smoothly.
This is a big question but there are a few ways to handle waiting on API data to load in general. Some are as simple as design changes to make the loading seem smoother. There are two solutions that I think will work for you,
Re-think where you are checking that they are logged in. You can do this at the app root and just pass in the logged in status to the nav bar so that you don't have to check by hand each time you load the nav bar. This way you are changing where the loading and waiting happens. You reach out to the API when the app is loading, not when the nav bar is loading and even store the logged in status in your state so that you can access it from anywhere in your app.
This is the quicker and dirtier solution, but you can just hide your nav bar until it has all the data it needs to load in completely. This solution would look something like this,
Wrap your entire nav bar template in this,
*ngIf="!(navbarLoading$ | async)"
Then in your component,
public navbarLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
ngOnInit(): void {
gapi.load('auth2', () => {
gapi.auth2.init({
client_id: 'MY_CLIENT_ID',
scope : 'email',
})
.then((data) => {
this.auth2 = data;
this.googleAuth = gapi.auth2.getAuthInstance();
this.log = this.handleAuthChange();
this.googleAuth.isSignedIn.listen(this.handleAuthChange);
this.navbarLoading$.next(false);
})
})
}