Resolver does not resolve if another data stream is added

痴心易碎 提交于 2020-06-23 08:33:30

问题


I am trying to use a resolver in order to retrieve data depending on the given parameters the route holds.

Unfortunately, the moment I add another data stream that my data depends on the resolver never actually resolves.

If I directly return an immediately resolving value everything works fine. I debugged the situation to see that I receive all partial information but it just fails to actually resolve in the end.

Here's a quick sample. Hit me up if there's more code needed to understand the problem.

MyService:

export class MyService {
  get(bar) {
    return of(new Foo(bar));
  }
}

SecondService (This one retrieves data from the backend):

export class SecondService {
  private readonly _observable: Observable<Bar>;
  constructor() {
    this._observable = merge(
      // Other manipulations
    ).pipe(
      // other manipulations
      shareReplay(1)
    )
  }

  observable(): Observable<Bar> {
    return this._observable;
  }
}

Resolver:

export class MyResolver {
  constructor(_secondService: SecondService, _myService: MyService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
    // Does not work - Simply does not resolve
    // return this._secondService
    //   .observable()
    //   .pipe(
    //     switchMap((bar) => this._myService.get(bar)),
    //   );

    // WORKS
    return of(new Foobar('sampleData'));
  }
}

Router:

const routes: Routes = [
  {
    path: 'someroute',
    component: SomeComponent,
    canActivate: [SomeGuard],
    resolve: {
      myData: MyResolver,
    },
  },
];

Component:

export class SomeComponent implements OnInit {
  constructor(private readonly _route: ActivatedRoute) {}

  ngOnInit() {
    this._route.data
      .subscribe((data) => {
      console.log('received:', data);
      this.myData = data;      
    });
  }
}

SomeComponent.html

<pre *ngIf="myData">
  Received: {{ myData | json }}
</pre>

回答1:


The answer to my problem is rather simple and had nothing to do with subscribing to the resolved observables, as I already did that within the (target)component.

In order for a resolver to finish, all the streams it depends on need to complete. If you happen to use hot Observable it is required to use another operator like take so that the stream completes at that location.

So, all the code remains the same, except that I changed the resolver to:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
  return this._secondService
    .observable()
    .pipe(
      take(1),
      switchMap((bar) => this._myService.get(bar)),
  );
}

@eduPeeth: Thank you for your answer/suggestions, unfortunately, it was a far more minor issue.




回答2:


Observable only get executed when you call Observable.subscribe() explicitly . I don't see anywhere in your code where you are subscribing to your Observables.

Note : Concept of resolve is related to Promise not with Observable.

Try :

export class MyResolver {
  constructor(_secondService: SecondService, _myService: MyService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
    // Does not work - Simply does not resolve
     return this._secondService
       .observable()
       .pipe(
         take(1),
         switchMap((bar) => this._myService.get(bar)),
       }     
       );

    // WORKS
    return of(new Foobar('sampleData')).pipe(
         take(1),
         switchMap((bar) => this._myService.get(bar)),          
     });
  }
}

Subscribe where you need the result.



来源:https://stackoverflow.com/questions/51306545/resolver-does-not-resolve-if-another-data-stream-is-added

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!