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>
The answer to my problem is rather simple and had nothing to do with subscribing to the resolved observables, as the framework already did that automagically.
In order for a resolver to finish, all the streams it depends on need to complete
. If you happen to use a 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With