I am trying to use an Observable/Behaviour subject in the following way:
I have a component which is displayed everywhere in the app as a background.
In a form-component that shows over that background I want
to take data that comes from the user and
to use this data to make an asynchronous call, and to use the result of that asynchronous call a method in that background component
So in my app.component.ts I have
<app-header></app-header>
<backround-component></background-component>
<router-outlet></router-outlet>
ln In my my app.routing.ts I have:
const appRoutes: Routes = [
{ path: '',
redirectTo: 'home',
pathMatch: 'full'},
{ path: 'home', component: HomeComponent },
{ path: 'form-component', component: Form component where the user submits the data },
];
In the form-component.html I have:
<button class="btn--submit" (click)="onClick()">Click</button>
So what I am trying to do is:
1) On data submission in the form-component call a method from the service that builds the request based on the submitted data:
onClick = function() {
this.service.makeAsynchCall(dataFromTheUser);
}
2) Make asynchronous call to remote API:
public makeAsynchCall(dataFromTheUser): Observable<any> {
// build the request based on the data
return Observable.create((observer) => {
this.someRemoteService.route(request, (response, status) => {
observer.next(response);
});
});
}
3) Subscribe to that observable in the background-component in a ngBeforeView lifecycle hook so that I can use the response:
ngBeforeView {
this.service.makeAsynchcall().subscribe(response =>
this.useTheResponse(response);
);
}
What I suppose that is happening is that on loading of that background component the asynch call first is forcefully invoked, then it forcefully invokes the method that expects data from the user, the data is not submitted yet and the request fails. I also tried another scenario - using BehaviourSubject / AsyncSubject as a connecting piece exploiting its role of both observer and Observable and make it notify other subscribers when the data has arrived and that didn’t work too. Thank you in advance for your help.
Update: tried the following based on the example in the answer below
Here is what I tried to do. In my subscriber, the next() method just prints the value received. Everything else is the same (except I didn't create the data model)
public update(data)
{
let request = {}; // build request object based on 'data'
this.source.next(data); // subscriber doesn't get the value (not printed)
// make async call
this.service.asyncCall(request, (response, status) => {
if (status == OK) {
console.log('got result'); // this prints, so we get here
this.source.next(data); // subscriber doesn't get the value (not printed)
}
});
}