Reputation: 331
I have a function to make expire date control for an Item. In this function i create an observable that checks if the item is new or not. If it´s new it works as expected but when a try to get some complementary data to define if its expiring date is when it does not work well.
If the call is made for a single Item it works fine but when i try to fill a table with several item it return undefined.
I think it is a matter of the async call. The subscriber is not waiting for the inner httprequest to finish before making a new call for the next item on the table.
1- Function that meke the call to get the expire date and set the proper status.
/* ValueGetter para mostrar en la tabla si la droga está vencida o vigente */
ctlVigencia(params){
let message: string;
this.ds.ctlVencimientoDroga(params.data._id, params.data.informacion.fecha.vencimientoCertificado, null)
.subscribe(res=> {
console.log(res);
if(res.fAsignada == null){
message= 'No deterninado'
} else {
let now = moment(new Date());
if (res.fAsignada > now ) {
message= 'Vigente'
} else {
message= ('Vencida')
}
}
})
return message
};
2) Function that returns the value of the expiration date.
/*Control vencimiento droga */
ctlVencimientoDroga(idSelected: string, vencimientoCertificado: Date, modeForm?: string){
let retesteos: Retesteo[];
const resObs= Observable.create((observer:Observer<{[key: string]: any}>) =>{
if (modeForm == 'nuevo'){
observer.next({fAsignada: vencimientoCertificado})
observer.complete();
} else{
this.rs.dataRetesteo.subscribe(res=>{
retesteos= res;
if (retesteos && retesteos.length == 0) {
if(vencimientoCertificado != null) {
observer.next({fAsignada: vencimientoCertificado});
} else {
observer.next(null);
}
}
/* From here and down is where is the problem */
if (retesteos && retesteos.length > 0){
let fechaUltimoRetesteoAprobado: Date;
retesteos.forEach(element => {
if (element.estado.estado == estadoAprobacion.Aprobado && (fechaUltimoRetesteoAprobado == null || element.fVencimiento > fechaUltimoRetesteoAprobado )){
fechaUltimoRetesteoAprobado= element.fVencimiento
}
});
observer.next({fAsignada: fechaUltimoRetesteoAprobado});
}
observer.complete();
});
this.rs.getById(idSelected);
}
})
return resObs;
}
}
I appreciate your help.
Upvotes: 0
Views: 390
Reputation: 7803
You are assigning the value to message
inside an asynchronous operation, but returning message
synchronously. Try modifying ctlVigencia
to return an Observable
and use map
on the response of ctlVencimientoDroga
.
ctlVigencia(params): Observable<string> {
return this.ds.ctlVencimientoDroga(params.data._id, params.data.informacion.fecha.vencimientoCertificado, null)
.pipe(map(res=> {
console.log(res);
if(res.fAsignada == null){
message= 'No deterninado'
} else {
let now = moment(new Date());
if (res.fAsignada > now ) {
message= 'Vigente'
} else {
message= ('Vencida')
}
}
return message;
}))
};
Please, not that I've changed subscribe
for pipe
and used map
. Now, when invoking ctlVigencia
you should subscribe
ctlVigencia(params).subscribe(message => console.log(message));
Upvotes: 0
Reputation: 29305
I would rewrite pretty much all of this to make use of operators...
ctlVigencia(params){
// use map operator, return observable
return this.ds.ctlVencimientoDroga(params.data._id, params.data.informacion.fecha.vencimientoCertificado, null)
.pipe(map(res=> {
console.log(res);
if(res.fAsignada == null){
return 'No deterninado'
} else {
let now = moment(new Date());
if (res.fAsignada > now ) {
return 'Vigente'
} else {
return 'Vencida'
}
}
}));
};
ctlVencimientoDroga(idSelected: string, vencimientoCertificado: Date, modeForm?: string){
let retesteos: Retesteo[];
if (modeForm == 'nuevo') {
// return mock observable
return of({fAsignada: vencimientoCertificado});
}
// return this observable and use map operator
return this.rs.dataRetesteo.pipe(
map(res=> {
retesteos = res;
if (retesteos && retesteos.length == 0) {
if(vencimientoCertificado != null) {
return {fAsignada: vencimientoCertificado};
} else {
return null;
}
} else {
let fechaUltimoRetesteoAprobado: Date;
retesteos.forEach(element => {
if (element.estado.estado == estadoAprobacion.Aprobado && (fechaUltimoRetesteoAprobado == null || element.fVencimiento > fechaUltimoRetesteoAprobado )){
fechaUltimoRetesteoAprobado = element.fVencimiento
}
});
this.rs.getById(idSelected); // unclear why or when this should happen
return {fAsignada: fechaUltimoRetesteoAprobado};
}
})
);
}
then whoever wants the value from ctlVigencia
needs to subscribe to it.
Upvotes: 1