I'm developing an Angular app and I use Rxjs, Observables and all the stuff to transfer data from my Data Access Layer to components.
I have a Service which gets Bootstrapping data (named B). Another service (named A) fetches these data and gives them to a component through a Subject.
My goal is to keep these data in my service A but only when I get the data the first time. So, I will use a Promise.
I need my Promise to "subscribe" to the Subject and then "unsubscribe" directly.
I tried the a BehaviorSubject, A ReplaySubject but the Promise never gets called...
The Bootstrap Service
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
The service which gets data and transfers them to components
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
Module and Bootstrapping config
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}
I would suggest keeping using Observables. There is the pipe operator share that share the result of the observable to everyone subscribing to this Observable. The call is made only once.
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments