Fork me on GitHub

ngPromiseStatus promise-aware UI elements.


A collection of Angular.js promise-aware directives and UI elements for your project

by Barak Chamo

 

ngPromiseStatus is a collection (starting with statusButton) of promise-aware Angular directives that make it easy to bind UI elements to the progress and eventual outcome of a promise.

Examples

Simple usage

This is a simplest use of the directive with only a promise (or array of) passed (and some default styles). See valid values for promises


Success
Error
Value (immediate)


Custom Status Classes

You can pass custom classes to be applied for each stage of the promise (progress, succcess and error). It plays nicely with Bootstrap btn classes


Success
Error
Error + Delay


Promise Values

The directive exposes several scope properties to the button's content (see docs). You can use them to give extra info on the promise's status.


Success {{$value}}

Resolved with value 'Done!'

Error {{$value}}

Rejected with error 'Error!'

Error + Delay {{$value}}

Rejected with error 'error!'



Example with custom classes and promise values

status-bar makes it really easy to create an alert container that reacts to promises.

This is an example with Bootstrap alert styles and the promise value exposed. It works just like the button, pass a promise or array of promises. Click on the buttons above to show the promises.


Success {{$value}}

I'm here, trigger the success button above.

Wait for it... Woohoo! Bummer... {{$value}}
Error {{$value}}

Me too, trigger the error button above.

Wait for it... Woohoo! Bummer... {{$value}}
Value {{$value}}

This one is for a value promise, try the button in the first row.

Wait for it... Woohoo! Bummer... {{$value}}


Documentation

You can install through bower:

bower install ng-promise-status

or through npm:

npm install ng-promise-status

or download the latest version from GitHub

To get started include ngPromiseStatus as a dependency in your angular app:

var app = angular.module('myApp', ['ngPromiseStatus']);

and you're good to go!


Multiple Promises (and other valid inputs)

The directives are built to work with multiple type of inputs:

promises
The promise from a $q.defer() or similar interfaces.
deffers
The deffered itself, saves the need of saving multiple references on scope.
promise arrays
An array of promises or deffereds.
other values
Any other value will not break but rather resolve immediately (implements $q.when).

CSS Classes

By default, the directives apply 4 classes to the elements depending on the state of the promise:

idle
There is no current promise in progress.

inprogress
There promise is still in progress, inprogress is used instead of progress so that it doesn't clash with Bootstrap progress bars.

success
The promise was resolved.

error
The promise was rejected.

ngPromiseStatus intentionally doesn't rely on any additional CSS files or required styling. It provides an easy interface in the form of class management that allows you to easy interact with promises using your existing styles and with no additional bloat to your project.


Scope Properties

The directive exposes special scope properties to the button's content that allow you to customize the button's content and interact with the promise's values and state.

name type details
$status string The status of the promise, same as the default class names: idle, inprogress, success and error
$value any Whatever value is passed upon resolution or rejection of the promise. If an array of promises is used, $value will be an ordered array of said whatevers.
$done boolean A convenience boolean that indicates if a promise is in progress.
$class string The class that is currently applied, overwritten with your custom configuration if provided.

Basic Use See default classes

The statusButton directive can be used by simply using the directive as a tag or attribute and passing a promise (or array of). See valid values for promises

When the button is clicked an internal handler is fired and assigns a promise handler to the assigned promise. Note that for that reason new promises are only detected on click.

Any ng-click handler assigned to the element will be called before the internal handler so you can easily use the same 'click' event to both assign a promise in your controller and for it to be detected by the button.

Here's an example:

Result:

Success

Template:

<status-button 
  ng-click="setSuccessPromise()" 
  promise="successPromise">
  <span>Success</span> 
</status-button>
                  

Controller:

// Create a new promise that will succeed in 3 seconds
$scope.setSuccessPromise = function(){
  // Set $scope.promise with a new promise
  $scope.successPromise = $q.defer();

  // React to promise in controller
  $scope.successPromise
    .promise
    .then(function(){
      console.log('Done from controller');
    });

  // Set a timeout for 3 seconds and resolve
  $timeout(function(){
    $scope.successPromise.resolve('Done!');
  }, 3000);
};
                  

Custom Configuration

You can configure a few key features of statusButton - classes applied on promise stages, delay and disable:

name type default details
idle_class string idle The initial class applied to the button and will applied after completion if a delay is specified.
progress_class string inprogress The class that will be applied to the button whenever a promise is in progress.
success_class string success The class that will be applied to the button when a promise is resolved (completed successfully).
error_class string error The class that will be applied to the button when a promise is rejected (resulted in an error).
progress_disable boolean true A toggle that determines if the button will be disabled when a promise is in progress.
delay number 0 The time (in milliseconds) it takes for the button to return to idle state upon promise completion (either success or error). 0 will not return to idle.

Here's an example for custom configuration using Bootstrap classes and a 2s delay:

Result:

Custom + Delay

Template:

<status-button 
  ng-click="setButtonPromise()" 
  promise="buttonPromise">
  options="buttonConfig">
  <span>Success</span> 
</status-button>
                  

Controller:

// Define your custom configuration
$scope.buttonConfig = {
  success_class:  'btn-success',
  error_class:    'btn-danger',
  progress_class: 'btn-warning',
  idle_class:     'btn-default',
  delay:          2000
};

// Create a new promise that will succeed in 3 seconds
$scope.setButtonPromise = function(){
  // Set $scope.promise with a new promise
  $scope.buttonPromise = $q.defer();

  // React to promise in controller
  $scope.buttonPromise
    .promise
    .then(function(){
      console.log('Done from controller');
    });

  // Set a timeout for 3 seconds and reject
  $timeout(function(){
    $scope.buttonPromise.reject();
  }, 3000);
};
                  

Scope Properties Available scope properties

Here's an example of using scope properties inside the button (promise is rejected with 'Error!'):

Result:

What's up? {{$value}}

Template:

<status-button 
  ng-click="setButtonPromise()" 
  promise="buttonPromise" 
  options="bootstrapConfig">
  <span>Success {{$value}}</span>
</status-button>
                  

Just like the statusButton, the statusBar directive can be easily put to work as a tag or attribute and passing a promise (or array of). See valid values for promises

When a promise is set and re-set a promise handler is assigned. This is managed by watching the promise passed but other hooks will soon be implemented.


Custom Configuration

You can configure some parameters of statusBar - classes applied on promise stages, delay and watch:

name type default details
idle_class string idle The initial class applied to the bar and will applied after completion if a delay is specified.
progress_class string inprogress The class that will be applied to the bar whenever a promise is in progress.
success_class string success The class that will be applied to the bar when a promise is resolved (completed successfully).
error_class string error The class that will be applied to the bar when a promise is rejected (resulted in an error).
watch boolean true A toggle that determines if the promise is watched. This should be left true for now until additional hooks are implemented.
delay number 0 The time (in milliseconds) it takes for the bar to return to idle state upon promise completion (either success or error). 0 will not return to idle.

Usage with Bootstrap classes and conditional content.

The statusBar directive assigns status classes to a container, it works well with Bootstrap <alert>s and other CSS framework components.


Here's an example with custom configuration and conditional content based on exposed scope properties.

Result:

Give it a go!

The bar will show up here

Wait for it... Woohoo! Bummer... {{$value}}

Bar Template:

<status-bar class="alert"
  promise="examplePromise" 
  options="alertConfig">
  <span ng-switch="$status">
    <strong ng-switch-when="inprogress">
      Wait for it...
    </strong> 
    <strong ng-switch-when="success">
      Woohoo!
    </strong> 
    <strong ng-switch-when="error">
      Bummer...
    </strong> 
    
    {{$value}}
  </span> 
</status-bar>
                  

Button Template:

<status-button 
  ng-click="setExamplePromise()" 
  promise="examplePromise">
  <span>Give it a go!</span> 
</status-button>