问题
In My Angular Application
I made several attempts to get the values using a BehaviorSubject to know when the value was changed or received. I can not get the values before loading the component.
Through this link you can see what you are returning:
https://dev.moip.com.br/v1.5/reference#listar-planos
data.service.ts:
dataOnChanged: BehaviorSubject<any> = new BehaviorSubject({});
getData() {
return new Promise((resolve, reject) => {
this.http.get(this.api_URL + 'plans/, this.httpOptions).subscribe((data: any) => {
// the result is
// data = {plans: Array(5)}
this.dataOnChanged.next(data);
resolve(data);
},
(response: any) => {
reject(response.error);
});
});
}
resolve.service.ts:
constructor(
private dataService: DataService, {
}
* Resolve
* @param {ActivatedRouteSnapshot} route
* @param {RouterStateSnapshot} state
* @returns {Observable<any> | Promise<any> | any}
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
return new Promise((resolve, reject) => {
Promise.all([
this.dataService.getData()
]).then(
() => {
resolve();
},
reject
);
});
}
routes.module.ts:
{
path: 'home',
component: HomeComponent,
resolve: {
data: ResolveService,
},
},
home.component.ts:
constructor(
public data: DataService,
) {
this.dataService.dataOnChanged.subscribe((result: any) => {
// no result
debugger;
});
The problem is that I can not load the data returned by HTTP GET before loading the component. I need to load the data before and show the screen.
回答1:
I think the best way to get the value will be to get it from the ActivatedRoute
In your component, if you inject the ActivatedRoute:
constructor(ars: ActivatedRoute) {
console.log(ars.snapshot.data.data) // This will log your value here
}
That way, you don't need the BehaviourSubject.
Here is an example on StackBlitz.
When you visit the /about route, it will get a value on a 2second delay to demonstrate
回答2:
Usage of BehaviorSubject
is redundant over here instead you can access the resolved data using the data
property of ActivatedRoute’s snapshot object or subscribe to ActivatedRoute data
Property which holds the static and resolved data of the current route
it's recommended to use Observables over promises. By converting to a promise you will lose the ability to cancel a request and the ability to chain RxJS operators.
From Docs
Rely on the router to call the resolver. Don't worry about all the ways that the user could navigate away. That's the router's job. Write this class and let the router take it from there.
The observable provided to the Router must complete. If the observable does not complete, the navigation will not continue.
data.service.ts:
getData():Observable<any> {
return this.http.get(this.api_URL + 'plans/, this.httpOptions);
}
resolve.service.ts:
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import {Observable} from 'rxjs';
@Injectable()
export class resolver implements Resolve<Observable<any>> {
constructor(private service:Service) {}
resolve() {
return this.dataService.getdata();
}
}
routes.module.ts:
{
path: 'home',
component: HomeComponent,
resolve: {
data: resolver,
},
},
home.component.ts:,
constructor( private route:ActivatedRoute) {
this.route.data.subscribe(value=>{
console.log(value);
});}
or
constructor( private route:ActivatedRoute) {
this.item=this.route.snapshot.data;
console.log(this.route.snapshot.data);
}
STACKBLITZ DEMO
来源:https://stackoverflow.com/questions/50545329/behaviorsubject-can-not-receive-value-with-subscribe