More in Routing

Ye Min Ko
Learn Ng
Published in
3 min readJun 23, 2021
Photo by Jake Weirick on Unsplash

Routing နဲ့ပတ်သက်ပြီး အတော်များများကို လေ့လာပြီးတဲ့နောက်မှာ သိသင့်သိထိုက်တဲ့တချို့ feature တွေကိုဆက်ပြီး လေ့လာရပါမယ်။

canDeactivate

Route တစ်ခုကနေ တစ်ခြား route ကိုကူးတဲ့အခါ လက်ရှိ route ကနေ ထွက်ခွာခွင့် ရှိမရှိ စစ်ဖို့အတွက် အသုံးပြုပါတယ်။ များသောအဖြင့် တစ်ခုခု edit လုပ်ပြီး မsaveပဲ တစ်ခြား route ကူးသွားခြင်းကို ကာကွယ်ဖို့အတွက် သုံးကြပါတယ်။

လက်တွေ့စမ်းသပ်ဖို့အတွက် ServerEditComponent မှာ အခုလိုရေးပါ။

export class ServerEditComponent implements OnInit { changesSaved = false; constructor(
private route: ActivatedRoute,
private serverService: ServerService,
private router: Router
) {}
onUpdate() {
this.serverService.updateServer(this.server);
this.changesSaved = true;
this.router.navigate(['../'], { relativeTo: this.route });
}
ngOnInit() {
this.route.params.subscribe((params: Params) => {
this.server = this.serverService.getServer(+params['id']);
});
}
}

Update လုပ်ဖို့ service နဲ့ ချိတ်ဆက်လိုက်တာ ဖြစ်ပါတယ်။ Update လုပ်ပြီးရင် အပေါ်အဆင့် route ကို navigate လုပ်သွားမှာပါ။

ဆက်လက်ပြီးတော့ update မနှိပ်ပဲ တခြား route ပြောင်းသွားမှာကို ကာကွယ်ဖို့ဆက်ရေးပါမယ်။

CanDeactivateGuardService ကို generate လုပ်ပါ။ အထဲမှာအောက်ပါ code တွေရေးပါ။

export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable({
providedIn: 'root',
})
export class CanDeactivateGuardService
implements CanDeactivate<CanComponentDeactivate>
{
canDeactivate(
component: CanComponentDeactivate,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return component.canDeactivate();
}
}

CanDeactivate အတွက် interface တစ်ခုကို ထည့်ပေးထားပါတယ်။ canDeactivate() ထဲမှာ ခေါ်သုံးမဲ့ component က override လုပ်မဲ့ canDeactivate() ကိုထပ်ဆင့် ခေါ်ပေးထားပါတယ်။

ပြီးရင်တော့ AppRoutingModule မှာအခုလိုရေးပါ။

const appRoutes: Routes = [
...
{
path: 'servers',
...
children: [
...
{
path: ':id/edit',
component: ServerEditComponent,
canDeactivate: [CanDeactivateGuardService],
},
],
},
]

ServerEditComponent မှာအခုလိုရေးပါ။

export class ServerEditComponent implements OnInit, CanComponentDeactivate { canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
if (!this.allowEdit) return true;
return this.changesSaved
? true
: confirm('Do you want to discard the changes?');
}
}

canDeactivate() ထဲမှာ deactivate လုပ်ခွင့်ရှိရင် true ပြန်ပေးပြီး မရှိရင် false ပြန်ပေးလိုက်တာ ဖြစ်ပါတယ်။

အားလုံးပြီးရင် အခုလိုစမ်းကြည့်ပါ။ Edit ထဲရောက်ပြီး update မနှိပ်ပဲတခြား route ကို သွားမယ်ဆိုရင် confirm box တက်လာမှာ ဖြစ်ပါတယ်။

canDeactivate Guard

Static Data

Route မှာ static data တချို့ ထည့်ပေးချင်ရင် သုံးပါတယ်။

PageNotFoundComponent မှာ အခုလိုရေးပါ။

HTML
<h3>{{ errorMessage }}</h3>
TypeScript
errorMessage: string = '';
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
this.errorMessage = this.route.snapshot.data['message'];
}

params, queryParams တို့လိုပဲ အခုလို snapshot နဲ့ရယူနိုင်သလို၊ subscribe လုပ်ပြီးလည်းရယူနိုင်ပါတယ်။

AppRoutingModule ရဲ့ wildcard မှာ အခုလိုပြင်လိုက်ပါ။

{
path: '**',
component: PageNotFoundComponent,
data: { message: 'Page Not Found' },
},

data property က js obj တစ်ခုကို လက်ခံပါတယ်။ ဒါကြောင့် ကိုယ်ထည့်ပေးချင်တဲ့ data ကို အခုလို ထည့်ပေးလိုက်တာပါ။

ပြီးရင်တော့ URL မှာ မသတ်မှတ်ထားတဲ့ route ကိုရိုက်ထည့်ရင် အခုလိုတွေ့ရမှာ ဖြစ်ပါတယ်။

Page Not Found

Dynamic Data (or) Resolver

Route အတွက် data ကို dynamic ရယူချင်ရင် အသုံးပြုပါတယ်။ Route ကိုမရောက်ခင် data ကို အရင်ယူပေးပါတယ်။

ServerComponent folder ထဲမှာ ServerResolverService ကိုအခုလို generate လုပ်လိုက်ပါ။

server-resolver.service.ts

ပြီးရင်တော့အောက်ပါ code ကိုရေးပါ။

@Injectable({
providedIn: 'root',
})
export class ServerResolverService implements Resolve<Server> {
constructor(private serverService: ServerService) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<Server> | Promise<Server> | Server {
return this.serverService.getServer(+route.params['id']);
}
}

Resolve ကို implement လုပ်ရပါတယ်။ resolve() method ကို override လုပ်ပြီး ရယူလိုတဲ့ data ကို return ပြန်ပေးရပါတယ်။

AppRoutingModule ရဲ့ ServerComponent route မှာအခုလိုရေးပါ။

{
path: ':id',
component: ServerComponent,
resolve: { server: ServerResolverService },
},

resolve property က js obj ကိုလက်ခံပါတယ်။ Key ကို server လို့ နံမည်ပေးလိုက်ပြီး ServerResolverServiceကို ထည့်ပေးလိုက်ပါတယ်။

ServerComponent မှာတော့ အခုလိုပြင်လိုက်ပါ။

ngOnInit() {
// this.route.params.subscribe((params: Params) => {
// this.server = this.serverService.getServer(+params['id']);
// });
this.route.data.subscribe((data: Data) => {
this.server = data['server'];
});
}

Static data ရယူတုန်းကလိုပဲ dynamic data ကိုရယူရပါတယ်။ ဒီနေရာမှာတော့ subscribe လုပ်ပြီး ရယူထားပါတယ်။

ပြန်စမ်းကြည့်ပါ server တွေ အရင်အတိုင်းဆက်ပြီး အလုပ်လုပ်နေတာ တွေ့ရမှာပါ။ မတူတာကတော့ params ကနေရယူတာမျိုး မဟုတ်တော့ပဲ resolver ကနေရယူလိုက်တာဖြစ်ပါတယ်။

Project

Password Manager app ရေးပါ။ နမူနာကို ဒီမှာ ကြည့်ပါ။ အဖြေကို ဒီမှာ ရနိုင်ပါတယ်။ App data အားလုံးကို AES 256 နဲ့ encrypt လုပ်ပြီးမှ localStorage မှာသိမ်းပေးပါ။ Encryption အတွက် crypto-js ကိုအသုံးပြုထားပါတယ်။ အောက်ပါအတိုင်း install လုပ်ပေးပါ။

npm install crypto-js
npm install @types/crypto-js

Implementation နမူနာကို ဒီမှာ ကြည့်နိုင်ပါတယ်။

Previous: Route Guards

Next: Observable

--

--

Ye Min Ko
Learn Ng

🌐 Web Developer | 👀 Self-Learner | 👨‍💻 An Introvert