everyone reading this :). Have a good time !
I was solving a problem in our project and cannot find a way to write DRY code
We have /article/:id URL in app, some articles are available by id - [1,2,3],
others are not [11,22,33] (for example) and i need to prevent user openning such ids.
I started to think how do i properly implement that logic - resolver( resolve() ) came to my mind in first place, but after awhile i liked canActivate more. Resolve is more about data preloading for page, not about letting/not letting users to activate a route. CanActivate is actually about this. I don't want to repeat data loading twice in resolve() and in component itself, so my finall choice is canActivate, i think it's perfect here.
So, i wrote this code:
//#TODO: unify with vacancy available guard
@Injectable()
export class ArticleAvailableGuard implements CanActivate {
constructor(
private _store: Store<fromArticles.State>,
private _router: Router
) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean | UrlTree> |
Promise<boolean | UrlTree> | boolean |
UrlTree {
let articleID = parseInt(route.params.id)
return this._store.pipe(
select(selectArticleById(articleID)),
map(article => !!article),
tap((dataAvailable) => {
if (!dataAvailable)
this._router.navigate(['/']).then()
})
)
}
}
It works as i need. But exactly same logic is used for page with alike entity as Article.
Only difference is data selector, instead of selectArticleById, i am using selectImagesById
I tried passing selector function in
{
path: 'article/:id',
component: ArticleSinglePageComponent,
canActivate: [ArticleAvailableGuard],
data: { selector: selectArticleById }
}
,
but received detected unserialized data error with Router.
How do i unify this Guard logic into one Guard and not split into same many Guars with only selector difference ?
question from:
https://stackoverflow.com/questions/65945328/how-to-unify-canactivate-logic-and-pass-selector-function-as-route-parameter-in 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…