softshipper
softshipper

Reputation: 34071

Wrapping a ajax call

I have a code, that will make inside the select function an ajax request.

  oSelect
    .select(function (oEvent) {
      return oEvent.getSource();
    })
    .select(function (oControl) {
      let oItem = oControl.getSelectedItem();
      let aKeys = oItem.getKey().split("/");
      return {plant: aKeys[0], wc: aKeys[1]};
    })
    .select(function (oSelectedItem) {

      let oModel = self.getModel("weightProtocolService");
      let oPlantFilter = new Filter("Plant", sap.ui.model.FilterOperator.EQ, oSelectedItem.plant);
      let oWcFilter = new Filter("WorkCenter", sap.ui.model.FilterOperator.EQ, oSelectedItem.wc);

      oModel.read("/CostCenterCalendarSet", {
        success: function (oData, oResponse) {
          return Rx.Observable.from(oResponse.data.results);

        },
        error: function (oError) {
          return Rx.Observable.throw(oError);
        },
        filters: [oPlantFilter, oWcFilter]
      });
    })
    .subscribe(function (oKey) {
      console.log(oKey);
    },
    function (err) {
      jQuery.sap.log.fatal(err);
    });

My problem here is, that it will subscribe first before the ajax response appears.

How can I solve the problem?

Upvotes: 0

Views: 59

Answers (2)

Olaf Horstmann
Olaf Horstmann

Reputation: 16882

If oModel.read returns a promise, then you can simply do the following:

....
return Observable.fromPromise(oModel.read("/CostCenterCalendarSet", {
        filters: [oPlantFilter, oWcFilter]
    })
);

If oModel.read does not return a promise, then you would need a custom observable:

....
return Observable.create(function(observer) {
    oModel.read("/CostCenterCalendarSet", {
        success: function (oData, oResponse) {
            return observer.onNext(oResponse.data.results);  // or just .next(..) in case you are using rxjs5+
        },
        error: function (oError) {
            return observer.onError(oError); // or just .error(..) in case you are using rxjs5+
        },
        filters: [oPlantFilter, oWcFilter]
    });
});

Upvotes: 1

André Werlang
André Werlang

Reputation: 5944

Assuming RxJS 5, replace the last select with a mergeMap and return a new observable:

.mergeMap(function (oSelectedItem) {

  let oModel = self.getModel("weightProtocolService");
  let oPlantFilter = new Filter("Plant", sap.ui.model.FilterOperator.EQ, oSelectedItem.plant);
  let oWcFilter = new Filter("WorkCenter", sap.ui.model.FilterOperator.EQ, oSelectedItem.wc);

  return new Observable(observer => {
    oModel.read("/CostCenterCalendarSet", {
      success: function (oData, oResponse) {
        observer.next(oResponse.data.results);
      },
      error: function (oError) {
        observer.error(oError);
      },
      filters: [oPlantFilter, oWcFilter]
    });
  });
})

Upvotes: 1

Related Questions