1

I have module of components(without routes) in my angular application.

This module have component that displays list of users in many other components.

But when user loads specific routes, list of users is doing another http request.

What i need is to load users from api after right after aplication loads,

not before(APP_INITIALIZER), something like preloading strategy, so when some component load user component, list of users is already there.

How solve this problem?

3
  • ...well, could be different ways .. consider router resolver (ie, pluralsight.com/guides/prefetching-data-for-an-angular-route ) .... if you really want you data load before "everything" , consider the following - You in you app define services and provide globally (with "providedIn: 'root' "), so in their constructors, make all needed http-requests => push data to their local , say, Replaysubjects -> whenever You inject the services' in components => subscribe to the service's public prop (the Subject) => you have your data instantly, kinda ... Commented Oct 29, 2021 at 9:20
  • You're pretty much describing resolvers there, ie. angular.io/api/router/Resolve. Enables you to preload any necessary data before navigating to a given route. Commented Oct 29, 2021 at 10:15
  • 1
    Resolvers are blocking loading module of pages. Besides resolvers are tided to routes and component. I don't wan't that. APP_INITIALIZER would do the same effect. I use initializer for different purpose. Anyway, it must load data async, in the background. Because it must not disturb users' work. Commented Oct 29, 2021 at 11:51

2 Answers 2

2

Resolvers are essentially a feature of the Angular routing core library that allows us to load and combine data from various sources (API services, databases, files etc.) and inject this data into the routing snapshot data before component/route loads

I will recommend use resolver here with the route add resolve attribute

{
  path: 'book',
  component: BookComponent,
  resolve: {
    pageData: APIResolver
  }
}

create resolver class

export class APIResolver implements Resolve<any> {
  // constructor(private apiService: ApiService, private router: Router){}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
  // return data from api here
  return 1;
  }
}

In the component you will get value before component load

constructor(private route: ActivatedRoute) { }
    
ngOnInit() {
  console.log(this.route.snapshot.data, 'testdata')
}

for more info you can check this demo stackblitz.com/edit/angular-ivy-cmevm

Sign up to request clarification or add additional context in comments.

Comments

0

In Angular 16, we can use a different approach.

We can create a resolver function

ng generate resolver my-resolver

Which will give us some template code for our resolver function, returning a ResolveFn from '@angular/router';. We can use this resolver function preload our component with data. Similarly to Sunny's answer. Create a resolve attribute in your routing module.

// routing module
{
  path: 'book',
  component: BookComponent,
  resolve: {
    pageData: myResolver
  }
}

Then, implement the resolver, which will fetch the data you need to preload.

// myResolver.resolver.ts
export const myResolver: ResolveFn<Promise<any>> = (
  route,
  state,
  myApiService: MyApiService = inject(MyApiService)
) => {
// assume we have a service to fetch our data.
// In this example, 'myApiService' has a function which returns the data we need. 
// It returns a Promise, but your service might return an Observable (which is totally OK.)
  return myApiService.getData(route.params['slug']);
};

Here's an example from Angular's documentation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.