With reference to the apps we already have set up,
Disclaimer: This is just to demonstrate a shared state. Not to be used in an ideal login/logout scenario. The best way to handle login/logouts are to use httpOnly cookies that use a token in BFF layer
Let's say we we want to handle user's authentication
create a folder, i am calling it "shared-library"
- cd shared-library
- ng new shared-library --create-application=false
- ng generate library KavyaMyUserServiceLibrary
- (cant use too generic names, it will not allow for public publish)
Inside
shared-library\shared-library\projects\user-service-library\src\lib\user-service-library.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserServiceLibraryService {
constructor() { }
private loggedIn = new BehaviorSubject<boolean>(false);
loggedIn$ = this.loggedIn.asObservable();
login(): void {
console.log("from library logging in", this.isLoggedIn)
this.loggedIn.next(true);
}
logout(): void {
console.log("from library logging out", this.isLoggedIn)
this.loggedIn.next(false);
}
get isLoggedIn(): boolean {
console.log("from library loggedIn", this.loggedIn.getValue())
return this.loggedIn.getValue();
}
}
- ng build KavyaMyUserServiceLibrary
- npm login
- cd dist/kavya-myuser-service-library
- npm publish --access public
This is the library i published:
https://www.npmjs.com/package/kavya-myuser-service-library
Time to install the library.
You need to install in all the apps individually.
BUT, in webpack.config.ts
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
name: 'account-management',
filename: 'remoteEntry.js',
exposes: {
'./Component': './src/app/app.component.ts',
},
shared: {
...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
'kavya-myuser-service-library': {
singleton: true,
strictVersion: false,
requiredVersion: '^0.0.1'
}
},
});
Make sure singleton is marked as true.
Also, DO NOT provide inside component/module again in remote apps.
It needs to be provided ONLY ONCE in the shell app.
shell:
hotel-reservation-system\src\app\app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { UserServiceLibraryService } from 'kavya-myuser-service-library';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
providers: [UserServiceLibraryService],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = 'hotel-reservation-system';
constructor(private userService: UserServiceLibraryService) {
}
ngOnInit() {
this.userService.loggedIn$.subscribe(res => {
console.log("from shell",this.userService.isLoggedIn, res)
})
}
login() {
this.userService.login()
}
}
account-management\src\app\app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { UserServiceLibraryService } from 'kavya-myuser-service-library';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = 'account-management';
constructor(private service: UserServiceLibraryService){}
isLoggedIn?: boolean;
ngOnInit() {
this.service.loggedIn$.subscribe(res => {
this.isLoggedIn = res;
console.log("from account-mgmt",this.service.isLoggedIn, res)
})
}
}
Now, when we click 'login' that is on shell app, the new logged in state is also reflected in account management app!
Comments
Post a Comment