Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: pass a value to the route data resolve

I'm trying to write a DataResolver service that will allow the Angular 2 router to preload data before initializing my component.

The resolver needs to call different API endpoints to fetch data appropriate to the route being loaded. Rather than having a resolver for each of my many components, I'm building one generic resolver. Thus, I'd like to pass custom input in the route definition that points to the correct endpoint. For instance, consider these routes:

app.routes.ts

appRoutes = [
  {
     path: 'project/:id',
     component: ProjectComponent,
     resolve: { data: DataResolver }
  },
  {
     path: 'store/:id',
     component: StoreComponent,
     resolve: { data: DataResolver }
  }
]

In the first instance, the resolver will need to call /path/to/resource1/id. In the second case, /path/to/resource2/id. Ideally, I would pass the endpoint as an argument in the route definition that would then be available in the DataResolver constructor.

Can this be done with a generic resolver class?

Angular 2.0.1 written in Typescript 2.0.3

like image 965
BeetleJuice Avatar asked Oct 28 '16 02:10

BeetleJuice


People also ask

How does Angular pass route parameters?

To pass route params and route query params in Angular, you have to use the ActivatedRoute service and use the params observable to get your desired values. The Angular Router provides a robust API so that you can do anything with it. That is it for this Angular route params tutorial.

What is resolve in Angular route?

So what is Angular Resolver? Angular Route Resolver is used for pre-fetching some of the data when the user is navigating from one route to another. It can be defined as a smooth approach for enhancing user experience by loading data before the user navigates to a particular component.

How to pass data in angular route component?

How to pass data in angular route component 1 Navigation within the application. ... 2 Using a state object of navigate () the method of Angular router object to pass data between components: Angular allows different ways of passing data between components. ... 3 Reading state object data in navigate () method. ... 4 Using Route params. ...

How to resolve data during navigation in angular router?

A data provider class can be used with the router to act as a resolver and it can resolve data during navigation. Using Resolve interface in Angular gives you one way to get data dynamically before navigating to a route.

What is the use of resolve in angular?

Using Resolve interface in Angular gives you one way to get data dynamically before navigating to a route. Resolve interface has a single method resolve () that is invoked when the navigation starts. The router waits for the data to be resolved before the route is finally activated.

How do I create a resolver in angular router?

First, create a separate class for the resolver in a file of its own: This will use the @angular/cli to generate a resolver named news: Implementing the Angular router’s Resolve interface requires the class to have a resolve method. Whatever is returned from that method will be the resolved data.


Video Answer


2 Answers

I don't know about making it available in the constructor, without using DI. But if you want it available in the resolve method, you could just add a data property in the route definition, and this would make it available to the ActivatedRouteSnapshot

{
  path: 'project/:id',
  component: ProjectComponent,
  resolve: { data: DataResolver },
  data: { path: 'project/:id' }
}

class DataResolve implements Resolve<string> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return route.data['path'];
  }
}
like image 93
Paul Samsotha Avatar answered Oct 05 '22 12:10

Paul Samsotha


This answer solved my problem, but I also needed this to be applied in case the route has multiple resolvers.

eg.

   {
    path: 'transactions/showcase/edit/:id',
    component: ClientsTransactionsFormComponent,
    resolve: {
      clients: Resolver,
      clientTransaction: Resolver,
      clientTransactionTypes: Resolver
    },

In that case I solved my issue by passing an array in data.

data: ['Clients/GetAll', 'ClientTransactions/GetByID/', 'ClientTransactionTypes/GetAll']

and also modified my resolver like this..

resolve(route: ActivatedRouteSnapshot) {
    let row = [];
    let id = "";

    Object.keys(route.data).forEach(e => {
      row.push(route.data[e]);
    })

    let path: string = row[0];
    delete row[0];

    route.data = row;

    if (path.lastIndexOf('/') == path.length - 1) {
      id = route.params['id'];
    }

    return this._httpService.httpGet(this.baseUrl + path + id);
  }

hope it helps anybody.

like image 41
itdoesntwork Avatar answered Oct 05 '22 14:10

itdoesntwork