We want to create a Angular Material social login button in a shared library that when clicked will call the method signInWithGoogle()
on a service that that has been assigned to the auth
property of the button. The service should implement this interface:
export interface IGoogleSocialAuth {
signOut()
signInWithGoogle()
}
Analysis
We are illustrating that it is possible to do this, but it should probably be considered an anti pattern.
The reason is that it couples the IGoogleSocialAuth
interface to the component.
Using an EventEmitter
to signal that the button is clicked, as done in Designing an Angular Social Login Button Presentation Component is usually a better approach.
Approach
The button design looks like this. It is disabled by default, and can be enabled by assign an Observable<boolean>
to the property isTOSAccepted$
that emits true
when the button should be enabled.
import { Component, OnInit } from '@angular/core';
import { Input } from '@angular/core';
import { Observable, of } from 'rxjs';
export interface IGoogleSocialAuth {
signOut()
signInWithGoogle()
}
@Component({
selector: 'fs-login-button',
templateUrl: './login-button.component.html',
styleUrls: ['./login-button.component.scss']
})
export class LoginButtonComponent implements OnInit {
@Input()
public auth: IGoogleSocialAuth
@Input()
public isTOSAccepted$: Observable<boolean> = of(false)
ngOnInit(): void { }
}
The template:
<button [disabled]="!(isTOSAccepted$ | async)"
(click)="auth.signInWithGoogle()"
mat-button
style="padding: 1rem;">
<mat-icon
[svgIcon]="SVG_CONSTANTS.GOOGLE_LOGO.name"></mat-icon> Login With Google
</button>
Test
Within app.component.ts
declare the following class:
class Auth {
signOut() {
console.log("Signing Out")
}
signInWithGoogle() {
console.log("Signing in with Google")
}
}
Create an instance of it and assign it to the auth
property on app.component.ts
.
We will create an Observable<boolean>
instance that emits true
as well:
auth = new Auth()
isTOCAccepted$: Observable<boolean> = of(true)
Within the app.component.html
template declare the button:
<fs-login-button [auth]="auth" [isTOSAccepted$]="isTOCAccepted$"></fs-login-button>
When the button is clicked it will log Signing in with Google
.