Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to consume a Promise from a service (native script / firebase)?

I have a userService that calls firebase.login() which returns a result of type Promise<User>. It is called like this:

firebase.login( { config... 
})
.then (function (result) { /* use result */}, 
       function (error)  { /* use error */ });

Elsewhere in the project, in a UI component, I need to react to the outcome of the login (i.e. success or error). I do not want to put any routing or similar logic into the user service, but rather have the other component control what happens next.

How is that done? How can another component react to it?

The component mentioned above is a class called LoginPage. It has a Login button which should start the Firebase login. The button is linked to a function (also called login()) in the LoginPage class.

XML:

<Button [text]="Sign in" class="submit-button" (tap)="login()"></Button>

login.component.ts

login() {
   this._userService.login(this.user)
   .then(function (data) {
      /* go to next screen */
    });
}

The above is obviously wrong, as the then clause will always be executed, regardless of the success or failure of the login.

Here is the login function in the userService:

@Injectable()
export class UserService {


  login(user: User) {

    firebase.login({
      type: firebase.LoginType.PASSWORD,
      email: user.email,
      password: user.password
    })
    .then( function (result) {
       console.log("Successful Login! " + JSON.stringify(result));
       return result;
     }, function (error) {
       console.log(error);
       return error; 
    });
 }
like image 351
Mundi Avatar asked Dec 06 '25 03:12

Mundi


1 Answers

UserService login method should return a promise to make it available for chaining:

  login(user: User) {
    return firebase.login(...)...
  }

In the original above login error was already caught, this leaves the promise with resolution that can be either a result or an error.

The preferable way to handle errors here is to not catch the error in the service itself. We always want to know if login request was successful or not.

  login(user: User) {

    return firebase.login(...)
    // second callback is optional if we don't need to log errors
    .then( function (result) { ... }, function (error) {
       console.log(error);
       return firebase.Promise.reject(error); 
    });
  }

This way an error can (and also should, Angular 2 will throw an error if there are uncaught promises) be caught and handled:

login() {
   return this._userService.login(this.user)
   .then(function (data) {
      /* go to next screen */
   })
   .catch(function (error) { ... });
}

It is always preferable to return promises, at least for testing purposes.

like image 138
Estus Flask Avatar answered Dec 08 '25 17:12

Estus Flask



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!