问题
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