Reputation: 331
Hello i am creating an angular async validator that has to wait for the response from a HttpRequest from a service.
I a need a function to return an observable of the information returned by the http call.
If a try diferent codes:
1- It doesn´t work because a is not defined due to the httprequest hasn´t finished when the function returns the a.
searchValue(controlName, controlValue){
this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a
HTTPrequest and make a subject emit a value.
let a
this.cts.dataGetByParamSubject.subscribe(res=>{
a=(res)
})
return of(a)
}
2- It doesn't work because it doesn´t return any value.
searchValue(controlName, controlValue){
this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a
HTTPrequest and make a subject emit a value.
let a
this.cts.dataGetByParamSubject.subscribe(res=>{
a=(res)
return of(a)
})
}
3- It returns a Subscription not an Observable.
searchValue(controlName, controlValue){
this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a
HTTPrequest and make a subject emit a value.
let a
return this.cts.dataGetByParamSubject.subscribe(res=>{
a=(res)
return of(a)
})
}
4- It returns an observable that when you map it the res is a Subscriber and i got lost.
searchValue(controlName, controlValue){
this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a
HTTPrequest and make a subject emit a value.
let a
return of(this.cts.dataGetByParamSubject.subscribe(res=>{
a=(res)
return of(a)
})
})
Service side:
getByParam(property, value): Observable<HttpResponses> {
let data
let params = new HttpParams()
.set('schema', this.tipoConfiguracion.codigo)
.set('property', property)
.set('value', value)
this.http.get<HttpResponses>(this.apiUrl + 'validation', {params: params}).subscribe(res=>{
this.dataGetByParamSubject.next({message: res.message, data: res.data, error: res.error})
})
return
}
How could i do this to work? Thank you for your help.
Upvotes: 0
Views: 962
Reputation: 9357
[UPDATE]: I've made some editions per comments.
searchValue(controlName, controlValue) {
// you don't need dataGetByParamSubject as it emits an object with the same
// shape of the returning of this.cts.getByParam
return this.cts.getByParam(controlName, controlValue);
}
Notice that as you have just one observable that have to be subscribed to after you get the return of getByParam
, you also could've used mergeMap
or concatMap
with no distinction.
Also, notice the take(1)
operator at the end of the pipe chain. I've added it because it looks like that this.cts.dataGetByParamSubject
is a long-lived stream and you just want one value, is that right?
You can learn a lot about operators on https://www.learnrxjs.io.
On the service, you should do:
getByParam(property, value): Observable<HttpResponses> {
let data
let params = new HttpParams()
.set('schema', this.tipoConfiguracion.codigo)
.set('property', property)
.set('value', value);
// there's no point in the dataGetByParamSubject here, as you will use
// it directly in your component.
return this.http.get<HttpResponses>(this.apiUrl + 'validation', {params: params}).pipe(
map((res: any) => ({
message: res.message,
data: res.data,
error: res.error
})
));
}
Upvotes: 2