Help please improve the page of the agreement on the use of personal data.

I made a small site that consists of several pages filled with text. The idea is that until the user puts a tick on the agreement page, he will not have access to other pages.

Here is the site: https://zlodiak.imtqy.com/ng2/feedback/1

Here are the sources: https://github.com/zlodiak/ng_feedback

The problem is that I created a service that contains global variables (in particular, a boolean variable that contains information about whether the user has confirmed the agreement or not) and connect it on each page that requires verification. That is, on all pages. While they are few, but as the site grows there will be a lot of them.

This is problem. Need a more elegant solution.

My global variable service looks like this:

import { Injectable } from '@angular/core'; import { Response, Headers, URLSearchParams } from '@angular/http'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Observable'; @Injectable() export class GlobalVarsService { private isAgreeOk = new BehaviorSubject(false); constructor() { }; getAgreeState(): Observable<boolean> { //console.log('this.isAgreeOk', this.isAgreeOk); return this.isAgreeOk; }; setAgreeState(state): void { //console.log('set isAgreeOk', state); this.isAgreeOk.next(state); }; } 

Here is the component of one of the pages:

 import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { GlobalVarsService } from '../services/global-vars.service'; @Component({ selector: 'app-question', templateUrl: './question.component.html', styleUrls: ['./question.component.scss'] }) export class QuestionComponent implements OnInit { constructor(private globalVarsService: GlobalVarsService, private router: Router) { } ngOnInit() { this.checkAgreeState(); } private checkAgreeState() { this.globalVarsService.getAgreeState().subscribe(state => setTimeout(() => { console.log('subscribe', state); if(!state) { this.router.navigate(['/agree']); } })); }; } 

It can be seen that the function code checkAgreeState (), GlobalVarsService import, router import, globalVarsService initialization, router initialization must be repeated on each page of the site. This is a dead end road.

I tried to transfer the validation functionality to app-component.ts, to the ngAfterViewChecked hook. But this method even worked, but hung the browser. By the way, the ngAfterViewChecked hook even if it contains only console.log () still hangs the browser, it is unclear why it even exists in angular.

    1 answer 1

    Use Route guards https://angular.io/guide/router#milestone-5-route-guards

     const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'agreement' }, { path: 'agreement', component: AgreementComponent }, { path: 'home', component: HomeComponent, canActivate: [AuthGuard] }, { path: 'page1', component: Page1Component, canActivate: [AuthGuard] }, { path: 'page2', component: Page2Component, canActivate: [AuthGuard] }, { path: '**', redirectTo: 'agreement' } ]; 

    Authguard

     import { GlobalVarsService } from '../_services'; import { Injectable } from '@angular/core'; import { Router, CanActivate } from '@angular/router'; @Injectable() export class AuthGuard implements CanActivate { constructor(private _router: Router, private _gvs: GlobalVarsService) { } canActivate() { if (this._gvs.getAgreeState()) { return true; } this._router.navigate(['/agreement']); return false; } } 
    • This is genius. Thank. True, I did not understand why after returning a redirect return false, but it is not essential. The main thing is that the problem is solved - cyklop77
    • return false; This is needed because canActivate should return true or false depending on whether this route can be activated, although it is quite possible that undefined will also come down. - Dimanoid