Open Source Spotlight: ngForge

header

Heya TriggerFolk!

This week we’re going to be taking a look at a great Open Source project started by Trigger.io user Andres Olave:

ngForge provides a set of idiomatic AngularJS wrappers for the
Forge modules that allow for easy & clean integration with Google’s AngularJS framework.

Here, in his own words, is Andres to tell you all about it…

An Introduction to ngForge

Angular & Trigger.IO are a great combination for developing mobile apps. Using either iOS or Crosswalk for Android it’s possible to build hybrid mobile apps we could only dream of in the past few years.

ngForge is a set of Angular wrappers for Trigger.io Forge modules with the aim to:

  1. Seemlessly switch between mobile & browser implementations
  2. Provide a AngularJS friendly experience:
    • Dependency Injection not globals.
    • Promises not callbacks.
    • $http API equivalency for the request module.
  3. Provide a basis for use in modern JS development:
    • Use the browser as the primary development environment – because there are many commonplace, well supported, free tools.
    • Don’t require trigger.io builds in the browser environment.
    • Be optimised for standard JS build tools: Grunt, Gulp, etc.
  4. Allow services to be configured & reconfigured on the fly in browser mode.

How it works

Using AngularJS emphasises the use of dependency injection. The typical use is to inject services into controllers, or the Angular’s $http service into services.

Let’s say you are building a web app with a service that has a saveLocally method:

With ngForge you can now instead use $forgePrefs which delegates to the forge.prefs module when running as a mobile app, and to localStorage when running in a browser.

For example, we can inject it into any service implemented in Angular:

This way AngularJS allows us to implement the service before it provides the $forgePrefs service and ngForge can detect whether it is running in a mobile environment or a browser.

  • if it’s a mobile environment ngForge delegates all service calls to the Trigger.io module.
  • if it’s a browser environment ngForge:
    • returns mock data – for example $forgeContacts returns mock data.
    • and/or implements a mock version of the module – for example $forgePrefs delegates to localStorage in browser mode.

In fact even if ngForge doesn’t mock out a method, it is still able to delegate service calls to Trigger.io in mobile environment mode.

Promises NOT callbacks

The Forge module API’s are currently still based on Node.js-style callbacks which often lead to callback hell and are not a natural fit with Angular’s Promises-based approach to deferred and asynchronous computation.

ngForge extends the Forge Module API’s with support for Promises which allows you to use them in the same way as you would in your regular Angular app.

For example, using standard Trigger.io you’d access forge.prefs like this:

With Promises, it instead becomes:

Much cleaner wouldn’t you agree?

Service Configuration

In browser mode, ngForge services can be configured by using Angular config methods. You may want to configure:

  1. Mock data: for example the mock contact book data used by $forgeContact, or
  2. Implementation configuration, for example what key to store data under when using the localStorage version of $forgePrefs.

Each service documents what is configurable. Here is an example config:

Using $forgeHttp instead of the forge.request module

Trigger.io’s forge.request module offers cross-origin access and native performance for HTTP request.

However, the request module’s API is based on a subset of the JQuery API and if you are using Angular it would be preferable to replicate the $http service API. (See the Angular $http service documentation for more details.)

This is what the $forgeHttp API looks like:

The following methods are not implemented as yet:

Additionally, the config object supports the following properties:

  • params{string|Object}: Params that are not already query strings are serialized as query strings and appended to the URL.
  • data{Object}: Data to be sent as the request message data. If it’s a get request then it is serialized as a query string and appended to the URL.
  • headers{Object}: Map of strings representing HTTP headers to send to the server.
  • cache{boolean|Object}: A boolean value or object created with $cacheFactory to enable or disable caching of the HTTP response.
  • timeout{number}: timeout in milliseconds
  • responseType{string}: See XMLHttpRequest.responseType.

All these methods return a promise that support the standard methods: then, catch & finally methods that take function with a single argument of the http response object. It also supports the deprecated success & error methods for handling responses. See the Angular Promises Documentation for more detail.

Results of GET are, by default, not cached. Caching is supported in the same way as in $http, that is, by default using simply the value true, or by an instance of $cacheFactory. (See the Angular $http caching documentation for more information)

We also support interceptors that allows you to implement cross cutting concerns for requests or response. Simply add interceptors to the $httpProvider as in the Angular documentation.

The future

AngularJS is a 3rd generation web framework but is already being replaced by 4th generation frameworks such as Angular2 & ReactJS. These feature simpler programming models, ECMAScript 2015 (or even TypeScript) & vastly superior performance.

There are some exciting Trigger.io updates coming that will make it possible for us to update ngForge with support for Angular 2 and Observables and we are planning broad framework support for ngForge in the near future.

I hope you enjoyed reading this quick introduction to ngForge.

Check the project out on GitHub and if you have any questions please feel free to drop me an email: andres@sportwize.me

Fork me on GitHub