Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Data from Guard to Component

My child route components are querying some data from an API. Currently I'm checking in the components if the id supplied as a route param is valid by checking the data the API returned.

I consider this as bad style and want to place the check into a guard that is checking if the supplied params are valid before the component gets activated.

However, I also want to save time and resources. This would require two API requests. Therefore I'm wondering if there is a possibility to pass data from the guard to the component. I thought about passing along with the route params but canActivate only provides a ActivatedRouteSnapshot which is read only.

Therefore my question: Is it possible to pass data from a guard to a component? Or is there another (even better) way to save resources and prevent multiple API requests in such cases?

like image 876
Christian Klemm Avatar asked Jan 28 '18 15:01

Christian Klemm


2 Answers

I think you're looking for a Resolver. With a resolver, you can load the data on the route transition before your components load. The setup is about exactly the same as the guard.

@Injectable()
export class YourResolver implements Resolve<YourObject> {

    constructor(private dataService: DataService) {
    }

    resolve(route: ActivatedRouteSnapshot): Observable<YourObject> {
        return this.dataService.getData().do(data=>{
           // you could potentially handle a redirect here if need be/
         });
    }
}

then in your route setup do

       {
            path: 'yourComponent', component: YourComponent,
            resolve: {
                data: YourResolver
            }, outlet: 'content'
        },
like image 171
JoshSommer Avatar answered Sep 22 '22 23:09

JoshSommer


Angulars canActivate is triggered before your component. In canActivate you can access the activated router, and check that "id" or witch parameter you want with your api, and after receiving the result from your api, you can return true or false. If you return false, your controller won't be triggered at all. So, the correct procedure for checking user rights is to check them in a canActivate class. Don't forget, you can chain your canActivate filters, and they are checked in the given order.

path:"doSomethingById/:id", controller: ExampleController,  canActivate: [AuthGuard, IdChek]

In the above example the IdCheck will run only if the AuthGuard returns true. And you controller will be fired only if both of them returns true.

like image 39
Zsolt Tolvaly Avatar answered Sep 24 '22 23:09

Zsolt Tolvaly