angulartypescriptangular-resolver

Resolver is not returning Data in Angular


I am new in Angular. I am trying to use resolver in my code. I have define routes for using resolver. Here is my routing.

{
   path: '',
   component: AppComponent,
   resolve: {
   post: ResolverService
   }
}

Then I create a resolver service.

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Post } from './post.data';


@Injectable({
  providedIn: 'root'
})

export class ResolverService implements Resolve<any> {

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const post = {
      userId: 101,
      id: 101,
      title: "abc",
      body: "xyz"
    }
    return post;
  }
}

This resolver is not returning the post data which I am trying to access form my component. Here is my component class code.

export class AppComponent {
  title = 'angular-resolver';
  page = 1;
  pageSize = 10;

  posts;
  constructor(private route: ActivatedRoute, private postService: PostService) {
  
    this.route.data.subscribe(data => console.log(data));
    
  }
}

Here console.log is returning an empty array. I think it should return the data I specified in the resolver class. Badly need some help. Can anyone tell me what is going on? Thanks in advance.


Solution

  • I think this is an edge case with the Resolve pattern, you can't use it on the bootstrap component (AppComponent), as it's not an actual route, but the app starts from it.

    If you want to preload something for the AppComponent you can use the APP_INITIALIZER instead, you can specify any number of them, and the app won't start until they are all resolved. They resolve by returning a Promise from them.

    AppModule

    export function resolveBeforeAppStarts(yourDataService: YourDataService) {
      return () => yourDataService.load().toPromise();
    }
    
    @NgModule({
      imports: [BrowserModule, FormsModule],
      declarations: [AppComponent],
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: resolveBeforeAppStarts,
          deps: [YourDataService],
          multi: true
        }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    

    YourDataService

    @Injectable({ providedIn: "root" })
    export class YourDataService {
      demoOnly: { userId: number; id: number; title: string; body: string };
    
      load = () =>
        of({
          userId: 101,
          id: 101,
          title: "abc",
          body: "xyz"
        }).pipe(
          delay(500),
          tap(x => (this.demoOnly = x))
        );
    }
    

    AppComponent

    export class AppComponent {
      data = this.yourDataService.demoOnly;
      constructor(private yourDataService: YourDataService) {}
    }
    

    Demo:

    https://stackblitz.com/edit/angular-ivy-txyfhd?file=src/app/your-data.service.ts