0

I have a resolver like this:

export class TaskResolver implements Resolve<Documents> {

  constructor(private taskService: TaskService) { }

  resolve(route: ActivatedRouteSnapshot): Observable<Documents> {
    const taskId = route.params.taskId;
    return this.taskService.DocumentsTask(taskId);
  }
}

And inside my component I have:

this.route.data.subscribe((data: { documents: Documents }) => {
     if (data.documents) {
    this.documents = data.documents;
  } else {
    this.router.navigate([`/error/404`]);
  }
});

I need to move the this.router.navigate([/error/404]); inside resolver, that way the resolver will check if the data is empty and redirect to error, and not the component. Or maybe move to auth guard that looks like this

canActivate(route: ActivatedRouteSnapshot): boolean {
    const taskId = route.params.taskId;
    if (taskId) {
      return true;
    }
  }

DocumentsTask(taskId) returns Observable

Miomir Dancevic
  • 6,726
  • 15
  • 74
  • 142

2 Answers2

0

The CanActivate Guard can return Observable<boolean | UrlTree> as of version 7.1.0 of Angular. This allows for the guard to evaluate a boolean and return a route redirect if it evaluates to false.

I wrote an answer a few days ago which goes over the implementation details but here's how I would approach it in your case:

First, create the guard:

import { Injectable } from '@angular/core';
import { CanActivate, Router, UrlTree, ActivatedRouteSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
// import your TaskService here

@Injectable()
export class RequireDocumentsGuard implements CanActivate {
  constructor(private router: Router, private taskService: TaskService) {
  }

  canActivate(route: ActivatedRouteSnapshot): Observable<boolean | UrlTree> {
    return this.taskService.DocumentsTask(route.params.taskId).pipe(
      catchError(() => of(false)),
      map(documents => !!documents || this.router.parseUrl('error/404'))
    );
  }
}

Then simply add the guard to your route in your RoutingModule:

{ 
  path: 'your/desired/route/:taskId', 
  component: YourComponentHere,
  canActivate: [RequireDocumentsGuard ]
}

Note: You have not posted your route structure so I will also make the point that you need to ensure that your 'error/404' route actually exists like:

{ 
  path: 'error/404', 
  component: Your404ErrorComponent
}

Hope that helps!

Darren Ruane
  • 2,385
  • 1
  • 8
  • 17
-1

use Auth Guard like this:

ng generate guard auth  

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from 
'@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from './auth.service';
import {Router} from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private auth: AuthService,
    private myRoute: Router){
  }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

    const taskId = next.params.taskId;
    if (taskId) {
      return true;
    }else{
      this.myRoute.navigate(["/error/404"]);
      return false;
    }
  }
}
Ajay Reddy
  • 1,475
  • 1
  • 16
  • 20