sushil bansal
sushil bansal

Reputation: 2013

best practice for returning data from a function which has a Callback

I have got a service which is calling a method with callback

import {someDataBaseFunction} from 'something/somthing';

class MyService{
    myServiceFunction(param1, param2){
        someDataBaseFunction(param1, param2, (error) => {
            if (error)
               console.log("error " + error);
            else
              console.log("success"); 
        });
    }
}

Based on my short stint with Angular2 there are 2 ways we can send this data back to Component:

1) Pass a callback function when calling myServiceFunction like

myServiceFunction(param1, param2, (data) => {
   // Do whatever with data
}) 

and change the signature of the myServiceFunction to take a callback function and call that callback when someDataBaseFunction resolves.

2) Creating a ReplaySubject like the following:

private mySubj$ = new ReplaySubject(1);

myServiceFunction(param1, param2){
   someDataBaseFunction(param1, param2, (error) => {
      if(error){
         console.log(error);
         this.mySubj$.error(error);
      }
      else {
         this.mySubj$.next('success'); //Whatever
      }
   });

   getDataObs$(){
      return this.mySubj$.asObservable();
   }
}

Out of these which one is good? Is there any other better approach?

Upvotes: 0

Views: 661

Answers (2)

Coding Pig
Coding Pig

Reputation: 66

Approach 2 is the way to go IMHO. Your service should not do too much (eg calling your custom function errorFunc) except for what it is meant to do.

Upvotes: 0

olivarra1
olivarra1

Reputation: 3399

I'd say neither... The first approach is simple and functional, but you can't compose/chain/map with other operations.

The second one doesn't make too sense: So you create a ReplaySubject so many subscribers can get the result, but yet wrapping it in another function? So either the component will have to do:

this.myService.myServiceFunction(...)
this.myService.getDataObs().subscribe(...)

Which could yield wrong values (imagine calling this thing a second time... getDataObs would yield the previous result of myServiceFunction) or if myServiceFunction returns the ReplaySubject, then why wrap it up in a ReplaySubject in the first place? Can't you just do:

myServiceFunction(param1, param2){
    return Rx.Observable.create(obs => {
        someDataBaseFunction(param1, param2, (error) => {
            if(error){
                console.log(error);
                obs.error(error);
            }
            else {
                obs.next('success'); //Whatever
            }
        });
    });
}

This way, the component would just call the function as

this.myService.myServiceFunction(...).subscribe(...)

If you want some sort of cache (like the someDataBaseFunction only gets called once), consider using the publish operator. For that, you'll have to create the stream and publish/connect it when initializing your service.

Upvotes: 1

Related Questions