Угловая проверка преобразователя маршрута, если данные пусты

У меня есть такой резольвер:

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);
  }
}

И внутри моего компонента у меня есть:

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

Мне нужно переместить this.router.navigate([/error/404]); внутрь резолвера, таким образом резолвер проверит, пусты ли данные, и перенаправит на ошибку, а не на компонент. Или, может быть, перейти к защите авторизации, которая выглядит так

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

DocumentsTask(taskId) возвращает Observable


person Miomir Dancevic    schedule 28.06.2019    source источник
comment
Защита авторизации — это правильное место для перенаправления на страницы 404, а не на преобразователь.   -  person user2216584    schedule 28.06.2019
comment
Можешь дать ответ   -  person Miomir Dancevic    schedule 28.06.2019
comment
Другие члены сообщества уже ответили .. :) Надеюсь, это решит вашу проблему.   -  person user2216584    schedule 28.06.2019


Ответы (2)


CanActivate Guard может возвращать Observable<boolean | UrlTree> начиная с версии 7.1.0 Angular. Это позволяет сторожу оценивать boolean и возвращать перенаправление маршрута, если оно оценивается как ложное.

Я написал ответ несколько дней назад, в котором рассматриваются детали реализации, но вот как я бы подошел к этому в вашем случае:

Сначала создайте защиту:

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'))
    );
  }
}

Затем просто добавьте охрану на свой маршрут в RoutingModule:

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

Примечание. Вы не опубликовали структуру своего маршрута, поэтому я также отмечу, что вам необходимо убедиться, что ваш маршрут «ошибка/404» фактически существует, например:

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

Надеюсь, это поможет!

person Darren Ruane    schedule 28.06.2019
comment
core.js: 15724 Ошибка ERROR: Uncaught (в обещании): EmptyError: нет элементов в последовательности - person Miomir Dancevic; 28.06.2019
comment
Какую версию Angular и RXJS вы используете? Эта ошибка известна из-за несоответствия версии. - person Darren Ruane; 28.06.2019
comment
rxjs: ^ 6.5.2, - person Miomir Dancevic; 28.06.2019
comment
А ваша версия Angular есть? - person Darren Ruane; 28.06.2019
comment
О, подожди, я знаю, в чем твоя проблема, я думаю. Вы изменили 'insert-absolute-redirect-url-here' на действительный маршрут? Я поместил это туда как шаблон, потому что не знаю структуру вашего маршрута. - person Darren Ruane; 28.06.2019
comment
Можешь добавить свой routes в свой пост и еще показать как ты разместил маршрут в UrlTree отдаче охранника? Потому что это должно просто работать. Также какой тип возврата taskService.DocumentsTask()? - person Darren Ruane; 28.06.2019
comment
Также маршруты такие же, как вы разместили - person Miomir Dancevic; 28.06.2019
comment
Извините, я не понимаю, что это значит. Вы можете уточнить? - person Darren Ruane; 28.06.2019
comment
Все ок, с маршрутами, и сделал как вы предложили - person Miomir Dancevic; 28.06.2019
comment
Хотя мои предложения были всего лишь шаблонами. Я спрашиваю вас, заменили ли вы шаблоны на вашу конкретную конфигурацию маршрута? - person Darren Ruane; 28.06.2019
comment
map(documents =› !!documents || this.router.parseUrl('/error/404'))); - person Miomir Dancevic; 28.06.2019
comment
Можете ли вы попробовать удалить первую косую черту, чтобы это было просто 'error/404'? - person Darren Ruane; 28.06.2019
comment
Хорошо, все выглядит хорошо в коде, который я разместил. Единственная другая вещь, которая может вызвать проблему, о которой я могу думать, это ваше фактическое определение маршрута. Не могли бы вы показать мне, как вы определили маршрут 'error/404', пожалуйста? - person Darren Ruane; 28.06.2019

используйте Auth Guard следующим образом:

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;
    }
  }
}
person Ajay Reddy    schedule 28.06.2019
comment
Вы просто проверяете, есть ли параметры, мне нужно проверить, что документы пусты ?? - person Miomir Dancevic; 28.06.2019