Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle connection loss page in Angular 7?

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:

  1. Click banner(Button) -> URL change to '/banner'
  2. Click brand(Button) -> URL change to '/brand'
  3. Disconnect network on that brand page
  4. Click back from browser-> ConnectionLostComponent and url is '/brand', that's okay
  5. Click back again -> ConnectionLostComponent but url is also changed to '/connection-lost'. that's what I'm facing the problem.

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.

like image 761
Ravi Sevta Avatar asked Feb 18 '19 15:02

Ravi Sevta


People also ask

How to check internet connection status in angular?

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.

What are the cause of connection lost?

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.

What does Connection lost mean?

If you hit a "Lost internet connection" error message, that means your client computer is having network issues.


2 Answers

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.

like image 64
AlokeT Avatar answered Oct 20 '22 18:10

AlokeT


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 ConnectionLostcomponent 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.

like image 30
Ravi Sevta Avatar answered Oct 20 '22 18:10

Ravi Sevta