What I want is that, If the network is not available, and the user tries to navigate to the next page ConnectionLost
Component would be there.
But if there is no network and user do not take any action means not navigating to the second page. then there should not be a connection-lost page. The user should stay on the current page.
For that, I have implemented canActivate guard as the following code:
@Injectable({
providedIn: 'root'
})
export class NetworkGuard implements CanActivate {
constructor(private router: Router, private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (window.navigator.onLine) {
return true;
} else {
if (!this.isConnectionLostComponent()) {
this.router.navigate(['/connection-lost'], {skipLocationChange: true});
}
return false;
}
}
private isConnectionLostComponent() {
// check whether connection lost component is added on not
return this.network.isActive;
}
}
It's working fine except for one condition.
That is if I click back or forward from the browser, its update URL connection-lost
to the address bar
How could I solve this problem? Can see the sample Here
steps to produce the issue:
I just don't want to update the URL with '/connection-lost', for that I added skipLocationChange: true
option to router.navigate
method in the NetworkGuard
, But still it's not working.
Step 1: You can install angular CLI, to prepare a basic project skeleton. Step 2: Create a new project for your workspace. It will create a basic skeleton or structure for your project. It will handle operations to check the status of your internet connection, whether it is online or offline.
A faulty router, modem or internet adapter. it could be a hardware or a software issue on your side. or simply – the issue could be network congestion.
If you hit a "Lost internet connection" error message, that means your client computer is having network issues.
I don't know is it the right solution or not for you but what I did in my project is following.
app.component.ts
constructor(){
this.onlineOffline = Observable.merge(of(navigator.onLine),
fromEvent(window, 'online').pipe(map(() => true)),
fromEvent(window, 'offline').pipe(map(() => false))
);
}
app.component.html
<ng-container *ngIf="onlineOffline | async; then thenTemplate; else elseTemplate"></ng-container>
<ng-template #thenTemplate>
<router-outlet></router-outlet>
</ng-template>
<ng-template #elseTemplate>
<app-no-network></app-no-network>
</ng-template>
Let me know if it is working the way you need to implement it or not.
After a little bit of search, and with help of @AlokeT's answer. I got a solution to this problem.
@AlokeT's suggestion is showing connection loss page as soon as the user lost his/her network. but my requirement is to show that connection loss page while he/she tries to navigate to another page.
And In this answer, I just added, that missing part.
For that, I just update that isNetworkStopped
flag from Guard, and because every CanActivate guard executes before navigation starts. So connection lost component would show while the user changing the path.
There is a code of NetworkService
which I'm using in NetworkGuard,
@Injectable({providedIn: 'root'})
export class NetworkService {
online: boolean;
isNetworkStopped = false;
constructor() {
this.online = window.navigator.onLine;
fromEvent(window, 'online').subscribe(e => {
this.online = true;
});
fromEvent(window, 'offline').subscribe(e => {
this.online = false;
});
}
}
Here in above code I just added a flag isNetworkStopped
. And updated that flag from NetworkGuard
, means while the user tries to navigate to next page and found no network.
And also removed navigation from NetworkGuard.
See my below, updated code of NetoworkGuard
@Injectable({providedIn: 'root'})
export class NetworkGuard implements CanActivate {
constructor(private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.network.online) {
return true;
}
this.network.isNetworkStopped = true;
return false;
}
}
And based on that flag I managed to show ConnectionLost component.
For that ConnectionLost
component is added on condition based to root component's template.
app.component.html
<router-outlet *ngIf="!networkService.isNetworkStopped"></router-outlet>
<app-connection *ngIf="networkService.isNetworkStopped"></app-connection>
And from ConnectionLost component, if the user clicks on the reload button. By checking network connection I updated isNetworkStopped
flag of NetworkService
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With