Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to figure out correct EventEmitter or Observable Syntax in Angular2 Services

I'm having a hard time finding much in the way of examples/guides for using observables in an Angular2 service. There is stuff for html templates binding with EventEmitter but that doesn't seem right for a service.

One of the big driving themes is getting away from Promises in Angular2 but I can't seem to get the new syntax correct.

What I'm Doing

  • I have a FirebaseAuth Service that can be injected into other services or components.
  • I have a function that does an async call to firebase, in my example to create a user
  • I want to return a Observable(to replace the promise) that other services can use to do other things like create a profile when this is resolved

I'm fine if promises are the best solution for this example but I'd like to figure out what the Observable Way is.

My Service:

/*DS Work on firebase Auth */
import {Injectable} from 'angular2/angular2';

@Injectable()
export class FirebaseAuth {
  ref = new Firebase('https://myfirebase.firebaseio.com');
  //check if user is logged in
  getAuth(): any {
    return this.ref.getAuth();
  }

  //register a new user
  createUser(user: any): Promise<any> {
    return new Promise((resolve, reject) => {
      this.ref.createUser(user, function(error, userData) {
        if (error) {
          reject(error);
          console.log('Error creating user:", error');
        } else {
          resolve(userData);
          console.log('Successfully created user account with uid:', userData.uid);
        }
       })  
    })
  }
};

How would I rewrite this to use Observable and/or EventEmitter?

like image 306
Dennis Smolek Avatar asked Oct 28 '15 00:10

Dennis Smolek


People also ask

Is an EventEmitter an observable?

EventEmitter is used in the directives and components to emit custom events either synchronously or asynchronously. Since EventEmitter class extends RxJS subject class, this means it is observable and can be multicasted to many observers.

What is EventEmitter can we use it in service if yes then how do you tell the use case?

EventEmitter is a public, documented type in the final Angular Core API. Whether or not it is based on Observable is irrelevant; if its documented emit and subscribe methods suit what you need, then go ahead and use it. Once a reference implementation of the spec is available, switch to it.

Can a service emit an event?

Service Bus can now emit events to Event Grid when there are messages in a queue or a subscription when no receivers are present.

How does EventEmitter work in Angular 5?

EventEmitterlink. Use in components with the @Output directive to emit custom events synchronously or asynchronously, and register handlers for those events by subscribing to an instance.


1 Answers

Actually it's almost the same thing, there a few changes

 createUser(user: any): any {
    return new Observable.create(observer => {
      this.ref.createUser(user, function(error, userData) {
        if (error) {
          observer.error(error);
          console.log("Error creating user:", error);
        } else {
          observer.next('success');
          observer.complete();
          console.log('Successfully created user account with uid:', userData.uid);
        }
       });  
    })
  }

And then you can suscribe to it (subscribe is the equivalent of then).

Here's a plnkr with an example using Observables

constructor() {
    this.createUser({}).subscribe(
        (data) => console.log(data), // Handle if success
        (error) => console.log(error)); // Handle if error
}

EventEmitter on the other hand is a Subject (documentation differs a little bit since angular2 moved to the last version, but it's still understandable).

_emitter = new EventEmitter();
constructor() {
    // Subscribe right away so we don't miss the data!
    this._emitter.toRx().subscribe((data) => console.log(data), (err) => console.log(err));
}
createUser(user: any) {
    this.ref.createUser(user, function(error, userData) {
        if (error) {
          this._emitter.throw(error);
          console.log('Error creating user:", error');
        } else {
          this._emitter.next(userData);
          this._emitter.return(); This will dispose the subscription
          console.log('Successfully created user account with uid:', userData.uid);
        }
    })  
}   

Here's a plnkr with an example using EventEmitter.

The difference in super short : Observable starts emitting the data when it finds subscribers; Subject emits info whether there are subscribers or not.

Note

In the EventEmitter example I used toRx(). This exposes the Subject but it's being refactored and we won't need toRx() anymore.

Useful resources Updated

RxJS In-Depth by Ben Lesh in AngularConnect's 2015 conference.

Thanks to Rob Wormald for pointing out this

You can see Sara Robinson's talk and her demo app and see it running here

like image 53
Eric Martinez Avatar answered Sep 21 '22 12:09

Eric Martinez