Issue
I work on a project that basically calls service method via a mediate class which is called ServiceHandler. In the component the console output of the result variable is undefined
.
Is there any solution to solve this problem?
Component
this.entityServiceHandler.saveEntityWithCondition(entity).subscribe(data => { this.result = data});
console.log(this.result);
ServiceHandler
public saveEntityWithCondition(entity): Observable<Entity>{
var subject = new Subject<any>();
this.subscriptions.push(
forkJoin({
conditionTrue: this.entityService.isConditionTrue(entity.property)
}).subscribe(({ conditionTrue }) => {
if (conditionTrue) {
this.entityService.save(entity).subscribe(
(response: Entity) => {
subject.next(response);
},
(errorResponse: HttpErrorResponse) => {
}
)
}
},
err => {},
() => {
}));
return subject.asObservable();
}
Service
public save(item: Entity) : Observable<Entity>{
public save(item: Entity): Observable<Entity> {
return this.httpClient.post<Entity>(`path`, item).pipe(catchError((err) => this.handleAndThrowError(err)));
}
}
Solution
The reason why you see undefined
is that you are mixing synchronous and asynchronous code and this often leads to problems. Just move the console.log
inside the subscribe
and it should be OK.
// Asynchronous code - takes some time to finalize
this.entityServiceHandler.saveEntityWithCondition(entity).subscribe(data => {
this.result = data;
console.log(this.resul) // This'll be shown
});
// Synchronous code - happens just after calling previous, doesn't wait for it
// to finish. This means, result is undefined
console.log(this.result);
EDIT:
I took a liberty and simplified your code a bit. You are doing lots of unnecessary things, like forkJoin
for just one observable. Or pushing a subscription to an Array, likely to close it later, but it's not needed when you refcator your code a bit.
import { filter, switchMap, catchError, EMPTY } from 'rxjs';
public saveEntityWithCondition(entity): Observable<Entity> {
// No need to forkJoin, just call the function and pipe it
return this.entityService.isConditionTrue(entity.property).pipe(
// This makes sure that conditionTrue is true indeed
filter(conditionTrue => conditionTrue),
// Then use switchMap to call the entity service and perform save
switchMap(() => this.entityService.save(entity)),
// And use catchError to handle possible issues
catchError(error => {
// handle error in some way - i.e. log it or something;
return EMPTY;
})
);
}
You don't need subject
anymore because you are returning the Observable<Entity>
directly.
You also don't need to push the Subscription
to an array, because thanks to the HttpClient you are using and the switchMap
operator included, it will handle unsubcribe
automatically, when save
is finished.
Answered By - mat.hudak
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.