0

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.

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

this.rs.getById(idSelected) is a httpRequest fired in a service i am subscribed on the service to store data on a variable and makes dataRetesteo Subject emit the http response. If i don´t call that function data Retesteo does´nt emit anything and the function does´nt work.
that's an unconventional set up but then I guess you just need to move it to above the return line or put it inside a defer if you want to only do that once subscribed
Thank you for your help i see i could write this much better and i learn a lot from this. But i have tried it and i get the error Property 'subscribe' does not exist on type '(params: any) => Observable<string>'
looks like you need to actually call the function ... ctlVigencia(params).subscribe(...)
Im doing that, but it give the error i posted. I have tried this ctlV(){return of(2)} and try to subscribe to ctlV but it gives the same error
|
0

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));

3 Comments

the operator syntax here is the older rxjs 5 syntax, now it uses .pipe(map( ... ))
I have tried this solution too, but have the same problem. I cant subscribe to cltVigencia(params) althoug i am returning the observable.
What do u mean by I can't subscribe to cltVigencia(params)? What is the error?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.