{ DreamFactory: 'Blog' }

Building an AngularJS application using the DreamFactory REST API backend

Posted by Andy Rai

Tue, Jan 5, 2016

angular.png

Now that DreamFactory 2.0 is live on Bitnami, our team has been busy building example apps to show how easy it is to use DreamFactory as your REST API backend. I’ve been working on DreamFactory’s AngularJS sample address book app and tutorial. This blog summarizes a few important things to know about getting started with the DreamFactory Angular sample app.

Background

The DreamFactory Angular sample app is basically a boilerplate application for getting started with DreamFactory. It contains all the setup required to communicate with your DreamFactory installation.

The code is very modular. Each functional piece of the application is a separate Angular module with its own services and directives. For example, there’s a login module with its own folder of templates, services, controllers, interceptors, etc. This module also takes care of managing session tokens and almost everything else related to authentication.

After following the configuration steps in the README, all that’s left is to make HTTP API calls with Angular’s $http service or $resource factory. Here are a few examples and a quick breakdown of sample application

Code Examples

Let’s first start with the app configuration. Using constants and interceptors for configuring API calls, the API call format for DreamFactory is:

http[s]:///api/v2/[ ]/[ ][?=]

The instance url is necessary in every API call. We can easily prepend it before every outgoing APIcall. For more detailed information on interceptors, check out the AngularJS docs.

In short, interceptors are factories which return an object with intercepting methods. For example, if we want to prepend every outgoing API url with the instance url we first do this:

angular.module('your-app', [])
.constant('INSTANCE_URL', 'http://sample-instance.cloud.dreamfactory.com')
.constant('DSP_API_KEY', 'YOUR-API-KEY')

We can then use an interceptor factory, like this:

.factory('httpInterceptor', function (INSTANCE_URL) {
 return {
  request: function (config) {
   // Prepend instance url before every api call
   if (config.url.indexOf('/api/v2') > -1) {
   config.url = INSTANCE_URL + config.url;
   };
 return config;
  }
 }
})

Like 'request', you can also use other methods which execute every time you request or receive a response. For example, you can have a 'response' which comes with apiResponse as an argument. The ‘response’ executes right after any API receives a response. The same goes for requestError and responseError methods in an interceptor.

Add the interceptor factory to the list of interceptors in your Angular module config.

.config([
 '$httpProvider',
 function ($httpProvider) {
  $httpProvider.interceptors.push('httpInterceptor');
 }
])

And that’s it. Now every API call is configured to include the instance url in the beginning of the url. You can also perform some other generic operations like setting headers before every call or wrapping/unwrapping data.

The other important configuration is to send the API key with every API call. You can achieve this with a bit of code in the run block of the Angular module.

.run([
 '$http', 'DSP_API_KEY',
 function ($http, DSP_API_KEY) {
  $http.defaults.headers.common['X-Dreamfactory-API-Key'] = DSP_API_KEY;
  }
])

This will add a header for API key in every call.

Login and registration

The login module takes care of user registration, login, and session management. Since we’ve already configured our app to prepend instance_url we don’t have to include it anymore our API calls.

angular.module('login')
.service('Login', [
 '$http', '$q', '$rootScope',
 function ($http, $q, $rootScope) {
  var handleResult = function (result) {
  // set default header for every call
   $http.defaults.headers.common['X-DreamFactory-Session-Token'] = result.data.session_token;
   $rootScope.user = result.data
  };
  // login user
  this.login = function (creds) {
   var deferred = $q.defer();
   $http.post('/api/v2/user/session', creds).then(function (result) {
    handleResult(result);
    deferred.resolve(result.data);
   }, deferred.reject);
   return deferred.promise;
  };
  //register new user
  this.register = function () {
   var deferred = $q.defer();
    $http.post('/api/v2/user/register?login=true', options).then(function (result) {
    handleResult(result)
    deferred.resolve(result.data);
   }, deferred.reject);
   return deferred.promise;
   }
 }
])

As shown above, there’s a dedicated service for handling the login and register calls to DreamFactory. The session token obtained from the server is added to the default list of headers and sent with every API call. If you want to exclude the token in specific API calls, you can use an interceptor as shown earlier (you can delete some headers before making the API call based on conditions). Here we assume that every API call needs the session token header.

Now in your controllers, you can call these functions and provide them with any necessary parameters. These functions return promises, so you can subscribe to error and success callbacks and show necessary notifications.

Getting records

Getting records is no different than making login and register API calls. Using Angular’s $http service we can make a simple GET API call to fetch records. Since we have already configured session-token, api-key headers and instance_url, no more extra configuration is required. Here’s an example of fetching contacts:

.controller([
 '$scope', '$http',
 function () {
  $http.get('/api/v2/_table/contact', {
   include_count: true
  }).then(function (result) {
   // success
   $scope.list = result.data.resource;
   $scope.meta = result.data.meta;
  }, function () {
  // error
  });
 }
])

In the above call, we add an extra parameter include_count which is converted to a query parameter by the $http service. This tells the server to embed record count in the API response.

Similarly, you can also use the filter query parameter to get a filtered list of records.

$http.get('/api/v2/_table/contact', {
 filter: 'id=2'
}).then(function (result) {
 // success
 }, function (error) {
  // error
})

What’s Next?

We’ve covered the basics of the Angular sample app in this blog post. Check out the GitHub repo for more demo code showing database CRUD operations as well as file CRUD operations. Please let us know what you think in the blog comments or on the forum.

 

Get started with DreamFactory with a free hosted DreamFactory development environment. Or, download and run it on the server, cloud, or desktop of your choice.

AngularJS DreamFactory Silver Tutorials

Weekly Digest

Recent Posts