简体   繁体   中英

Angular 2 Service - Observable that uses a function with has callback function as argument

I have an Angular 2 service which consumes a SOAP Web Service. In order to do so, I use a Javascript SOAP client which has a callback function. I know that the result of a service method could be an Observable or a Promise , but I don't know how to go from the callback function back to the service.

Here is my current code:

import { Injectable } from '@angular/core';
declare var SOAPClient: any;//<-- The library I'm using, it doesn't have types

@Injectable()
export class SoapService {
  connection_url: Map<string,string>;
  constructor() {
   this.connection_url = new Map<string, string>();
   this.connection_url.set('Example', 'http://localhost:8080/MYAPP_EJB/ExampleSvc');
  }

  consume(service_name: string, method: string, parameters?: Map<string,any>){
   var that = this;
   return new Promise<any>(function(resolve){
      var params = new SOAPClientParameters();
      if(parameters !== null){
        for (let parameter of parameters.keys()){
          params.add(parameter,parameters.get(parameter));
        }
      }
      //Below is the line where I use the function with the callback function argument (function(j)), where j represents the response from the Web Service
      SOAPClient.invoke(that.connection_url.get(service_name), method,params,true,
      function(j){
              return new Promise<any>(function(resolve){
                console.log('Web Service Answer: ' + j.answer.entry.value);
                return j;
              });    
      }); //End of SOAPClient.invoke()
    }); //End of promise of consume()
  }//End of consume()
}//End of class

What can I do to make consume() provide the Web Service response to a component? Will I need to introduce some modifications to SOAPClient?

Thank you.

Edit: Solution

I used Robin's answer and worked with bindCallback (same idea as fromCallback , see bindCallback for reference), using SOAPClient.invoke as argument for that function. The resulting function is the same as the original, but without the need of a callback function, returning a Observable instead, which I can subscribe and then resolve the promise of consume() .

The new code:

import { Injectable } from '@angular/core';
import * as Rx from "rxjs";
declare var SOAPClient: any;//<-- The library I'm using, it doesn't have types

@Injectable()
export class SoapService {
  connection_url: Map<string,string>;
  invokeSoapClient: any;
  constructor() {
   this.connection_url = new Map<string, string>();
   this.connection_url.set('Example', 'http://localhost:8080/MYAPP_EJB/ExampleSvc');
   this.invokeSoapClient = <any> Rx.Observable.bindCallback(SOAPClient.invoke);
  }

  consume(service_name: string, method: string, parameters?: Map<string,any>){
   var that = this;
   return new Promise<any>(function(resolve){
      var params = new SOAPClientParameters();
      if(parameters !== null){
        for (let parameter of parameters.keys()){
          params.add(parameter,parameters.get(parameter));
        }
      }
      var invokeObs = that.invokeSoapClient(that.conexion_url.get(service_name), method, params, true);
      invokeObs.subscribe(r => {resolve(r[0])}); //r is the answer from SOAPClient invoke, I just needed the response part.
    }); //End of promise of consume()
  }//End of consume()
}//End of class

The best way would eb to create a observable from your callback. You can easily create a observerable from a callback. check this out

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM