Skip to content

Run multiple resolvers concurrently in router. #14279

Closed

Description

@Iverson

I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
I set multiple resolvers in my route:

export const routes: Routes = [
  {
    path: '',
    children: appRoutes,
    canActivate: [AuthGuard],
    resolve: {
      capabilities: CapabilitiesResolver,
      userInfo: OrganizationUserResolver,
      organizations: OrganizationResolver
    }
  }
]

each of them implements Resolve interface and return Observable:

@Injectable()
export class CapabilitiesResolver implements Resolve<Endpoint[]> {
  constructor(private capabilitiesService: CapabilitiesService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Endpoint[]> {
    return this.capabilitiesService.fetch()
  }
}

as result all http requests run sequentially and this is not useful behavior for UX. But if resolvers return Promise instead of Observable:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Endpoint[]> {
    return this.capabilitiesService.fetch().toPromise()
  }

then all requests will be ran concurrently, very implicit behavior...

Expected behavior
No matter what resolve() method return (Observable or Promise) all async operations should be ran concurrently.

What is the motivation / use case for changing the behavior?
For users: Improve UX when router pre-fetch data.
For developers: More explicit router API.

Please tell us about your environment:
@angular/cli: 1.0.0-beta.30
node: 6.2.2
os: darwin x64
@angular/common: 2.4.1
@angular/compiler: 2.4.1
@angular/core: 2.4.1
@angular/forms: 2.4.1
@angular/http: 2.4.1
@angular/platform-browser: 2.4.1
@angular/platform-browser-dynamic: 2.4.1
@angular/router: 3.4.1
@angular/compiler-cli: 2.4.1

  • Angular version: 2.4.1

  • Browser: all

  • Language: TypeScript 2.0.3

Activity

  1. saedwards commented on May 17, 2017

    @saedwards

    This looks interesting. I've currently got the problem whereby at a single route I need to wait for data from the result of one resolvers service call to complete before calling another service with the previous resolved data. How would I be able to do this with the above changes?

  2. bumbapartha commented on May 26, 2017

    @bumbapartha

    We could have a chain of resolver dependency to solve this problem. May be the the following approach can be used.

    {
        path : '',
        component : '',
        resolve : {
            data1 : {
                resolver: Data1Resolver
                resolve : {
                    subdata1 : SubData1Resolver
                }
            },
            data2 : Data2Resolver
        }
    }
    

    Note : We can get the data loaded by Data1Resolver inside the resolve method of SubData1Resolver. So that synchronous resolver can be called and data can be shared.

  3. saedwards commented on May 29, 2017

    @saedwards

    That looks good. Just to clarify - You'd get the choice of both, data1 & data2 resolve concurrently. And subdata1 values resolve sequentially after data1 values are resolved. Is this not available already? It sounds like it would be a solution to a very common problem, I haven't found anything on the Angular site.

  4. added 2 commits that reference this issue on Jul 18, 2017
    ad3029e
    ec89f37
  5. bhaidar commented on Aug 10, 2017

    @bhaidar

    Is this feature available now in Angular 4? If I have multiple resolvers, would they run concurrently?

  6. added a commit that references this issue on Aug 11, 2017
    e373348
  7. added 2 commits that reference this issue on Aug 26, 2017
    f06bc6b
    3e8033e
  8. brandon7810 commented on Jan 9, 2018

    @brandon7810

    Hi I would like to know the state of this issue since I do not want to run my resolvers concurrently. I would need them to be executed sequentially. @hibumbapartha is your code working?

  9. MickL commented on Jan 22, 2018

    @MickL

    Actually i need the opposite: One guard (resolve or canActivate) should WAIT for the previous before it executes. I have to prevent concurrent execution.

  10. felipe-norato commented on Jan 25, 2018

    @felipe-norato

    @MickL I need the same thing!

  11. MickL commented on Jan 26, 2018

    @MickL

    I opened a issue here: #21702

    Feel free to give it a thumbs up

  12. stevedeighton commented on Mar 21, 2018

    @stevedeighton

    So to clarify, there's no in built way to resolve multiple one after each other, like how it used to work?

    'cause if so this makes me weep a little!

  13. angular-automatic-lock-bot commented on Sep 13, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  14. locked and limited conversation to collaborators on Sep 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions