PeiSong
PeiSong

Reputation: 929

How to resolve application-level data in angular 4?

Let's say I have a global config that should be loaded for all the URLs.

For example:

/
/users
/users/abc

I can manually to add the resolver to all the urls one by one, but in that case I have to update global config from each component which capture the route data, right? Is there a better way to deal with this?


Let's say we have multi modules:

App Module
/login
/sign-up

User Module
/user/list
/user/:id

Product Module
/product/list
/product/:id

@DeborahK 's solution we will still have to add resolver to each module's root route, I can tell this will definitely work. But is there a way to just apply once at one place?

Upvotes: 5

Views: 1838

Answers (2)

sarora
sarora

Reputation: 914

I'm also trying to figure best approach here for angular 4, and from my tests it appears that

a) You cannot put the resolver at the top-level i.e. resolve won't cascade down if you have multiple feature modules.

b) Putting the resolver on the root of each feature module where you need the data causes the resolver to run unnecessarily (e.g. each time you navigate back and forth between components from various feature modules).

So I believe resolvers don't appear well-suited to application-wide data loading, and it's probably best to explore other techniques such as APP_INITIALIZER or ways to inject something into bootstrap (e.g. this looks interesting: angular2 bootstrap with data from ajax call(s) ). Would be interested to know what others have found best suited. Good luck and please update if you find anything of interest.

Upvotes: 0

DeborahK
DeborahK

Reputation: 60568

If you have parent and child routes you can set a resolver on the parent and use it in the child. I have an example here: https://github.com/DeborahK/Angular-Routing/tree/master/APM-Final

My parent and child routes look like this. Notice the resolver is only on the parent.

  {
    path: ':id/edit',
    component: ProductEditComponent,
    resolve: { product: ProductResolver },
    canDeactivate: [ProductEditGuard],
    children: [
      {
        path: '',
        redirectTo: 'info',
        pathMatch: 'full'
      },
      {
        path: 'info',
        component: ProductEditInfoComponent
      },
      {
        path: 'tags',
        component: ProductEditTagsComponent
      }
    ]
  }

Then you can read the resolver data from the child like this:

ngOnInit(): void {
        this.route.parent.data.subscribe(data => {
            this.product = data['product'];

            if (this.productForm) {
                this.productForm.reset();
            }
        });
    }

I'm watching for changes so have the subscribe. If you don't need to watch for changes you can use the snapshot.

Upvotes: 3

Related Questions