Categories: angularjs

AngularJS $http service example-server communication

AngularJS $http service is used for asynchronous server communication. This post explains $http service in great details, specially $q & promise, with a complete CRUD application example, using AngularJS front-end client, communicating asynchronously with Spring REST API based back-end. You can plug-in your own server with this client to play with.

It is important to emphasize that if you have a RESTful API on your server, you can reduce the amount of code you need to write for server communication by using $resource service instead. If you want to learn $resource, a complete post with CRUD example is available at Angularjs Server Communcation using ngResource-CRUD application example.
To learn more about AngularJS services in general, please visit our AngularJS Services Tutorial.

To learn more about Spring REST API in general, don’t forget to visit Spring REST API Tutorial


What is $http

AngularJS $http service allows us to communicate asynchronously with server endpoints using XHR [browser’s XMLHttpRequest Object] API. $http is designed for general purpose AJAX calls that can deal with both RESTful & Non-RESTful API on your server. For anyone coming from jQuery background, $http can be treated somewhat equivalent to jQuery.ajax. The $http API is based on the deferred/promise APIs exposed by the $q service which is an implementation of Promise interface, based on Kris Kowal’s Q approach, which is a standardized way of dealing with asynchronous calls in JavaScript.

The Promise API comes with following flow:

  • 1. Each asynchronous task will return a promise object.
  • 2. Each promise object will have a then function that can take two arguments, a success handler and an error handler.
  • 3. The success or the error handler in the then function will be called only once, after the asynchronous task finishes.
  • 4. The then function will also return a promise, to allow chaining multiple calls.
  • 5. Each handler (success or error) can return a value, which will be passed to the next function in the chain of promises.
  • 6. If a handler returns a promise (makes another asynchronous request), then the next handler (success or error) will be called only after that request is finished.

Let’s take a simple example to understand $http.

// Simple GET request example :
$http.get('/someUrl').
  then(function(response) {
    // this callback will be called asynchronously when the response is available
  }, function(response) {
    // this callback will be called asynchronously if an error occurs or server returns response with an error status.
  });

In above example, then function takes two callbacks as parameter. First parameter gets called if the response is success. In case of failure, second parameter gets called. Both of callback parameters takes response as input.

The response object has these properties:

data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers – {function([headerName])} – Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.

What about Server

Our Server is Spring Based REST API, taken from this post. Basically, This is what our REST API does:

GET request to /api/user/ returns a list of users
GET request to /api/user/1 returns the user with ID 1
POST request to /api/user/ with a user object as JSON creates a new user
PUT request to /api/user/3 with a user object as JSON updates the user with ID 3
DELETE request to /api/user/4 deletes the user with ID 4
DELETE request to /api/user/ deletes all the users

For this post we will reuse the Server from mentioned post. We will just tweak the properties in User model object to meet the client from this example.

1. Client Part

Declare Module [app.js]

'use strict';

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

Create Service [user_service.js]

Let’s create the service (using module.factory as discussed in AngularJs Service Post). This service will then be injected in controller.

'use strict';

App.factory('UserService', ['$http', '$q', function($http, $q){

 return {
  
    fetchAllUsers: function() {
   return $http.get('http://localhost:8080/SpringMVC4RestAPI/user/')
   .then(
     function(response){
      return response.data;
     }, 
     function(errResponse){
      console.error('Error while fetching users');
      return $q.reject(errResponse);
     }
   );
  },
    
    createUser: function(user){
   return $http.post('http://localhost:8080/SpringMVC4RestAPI/user/', user)
   .then(
     function(response){
      return response.data;
     }, 
     function(errResponse){
      console.error('Error while creating user');
      return $q.reject(errResponse);
     }
   );
  },
    
    updateUser: function(user, id){
   return $http.put('http://localhost:8080/SpringMVC4RestAPI/user/'+id, user)
   .then(
     function(response){
      return response.data;
     }, 
     function(errResponse){
      console.error('Error while updating user');
      return $q.reject(errResponse);
     }
   );
  },
    
   deleteUser: function(id){
   return $http.delete('http://localhost:8080/SpringMVC4RestAPI/user/'+id)
   .then(
     function(response){
      return response.data;
     }, 
     function(errResponse){
      console.error('Error while deleting user');
      return $q.reject(errResponse);
     }
   );
  }
  
 };

}]);

Create Controller [app_controller.js]

Controllwe will have our service injected, which it will then use from inside it’s functions exposed to User interface.

'use strict';

App.controller('AppController', ['$scope', 'UserService', function($scope, UserService) {
          var self = this;
          self.user={id:null,username:'',address:'',email:''};
          self.users=[];
              
          self.fetchAllUsers = function(){
              UserService.fetchAllUsers()
                  .then(
                  function(d) {
                    self.users = d;
                  },
                 function(errResponse){
                  console.error('Error while fetching Currencies');
                 }
                );
          };
           
          self.createUser = function(user){
              UserService.createUser(user)
                .then(
                      self.fetchAllUsers, 
                  function(errResponse){
                    console.error('Error while creating User.');
                  } 
                  );
          };

         self.updateUser = function(user, id){
              UserService.updateUser(user, id)
                .then(
                  self.fetchAllUsers, 
                  function(errResponse){
                    console.error('Error while updating User.');
                  } 
                  );
          };

         self.deleteUser = function(id){
              UserService.deleteUser(id)
                .then(
                  self.fetchAllUsers, 
                  function(errResponse){
                    console.error('Error while deleting User.');
                  } 
                  );
          };

          self.fetchAllUsers();

          self.submit = function() {
              if(self.user.id===null){
                  console.log('Saving New User', self.user);    
                  self.createUser(self.user);
              }else{
                  self.updateUser(self.user, self.user.id);
                  console.log('User updated with id ', self.user.id);
              }
              self.reset();
          };
              
          self.edit = function(id){
              console.log('id to be edited', id);
              for(var i = 0; i < self.users.length; i++){
                  if(self.users[i].id === id) {
                     self.user = angular.copy(self.users[i]);
                     break;
                  }
              }
          }
              
          self.remove = function(id){
              console.log('id to be deleted', id);
              if(self.user.id === id) {//clean the form if the user to be deleted is shown there.
                  self.reset();
              }
              self.deleteUser(id);
          }

          self.reset = function(){
              self.user={id:null,username:'',address:'',email:''};
              $scope.myForm.$setPristine(); //reset Form
          }

      }]);

Create FE Application [ServiceExample.html]

It’s a trivial user management CRUD application with AngulasrJS, using bootstrap for styling. We have modularized it a bit, by keeping module,controller & service in different files.

&lt;html&gt;
  &lt;head&gt;  
    &lt;title&gt;AngularJS $http Example&lt;/title&gt;  
    &lt;style&gt;
      .username.ng-valid {
          background-color: lightgreen;
      }
      .username.ng-dirty.ng-invalid-required {
          background-color: red;
      }
      .username.ng-dirty.ng-invalid-minlength {
          background-color: yellow;
      }

      .email.ng-valid {
          background-color: lightgreen;
      }
      .email.ng-dirty.ng-invalid-required {
          background-color: red;
      }
      .email.ng-dirty.ng-invalid-email {
          background-color: yellow;
      }

    &lt;/style&gt;
     &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css&quot;&gt;
     &lt;link rel=&quot;stylesheet&quot; href=&quot;app.css&quot;&gt;
  &lt;/head&gt;
  &lt;body ng-app=&quot;myApp&quot; class=&quot;ng-cloak&quot;&gt;
      &lt;div class=&quot;generic-container&quot; ng-controller=&quot;AppController as ctrl&quot;&gt;
          &lt;div class=&quot;panel panel-default&quot;&gt;
              &lt;div class=&quot;panel-heading&quot;&gt;&lt;span class=&quot;lead&quot;&gt;User Registration Form &lt;/span&gt;&lt;/div&gt;
              &lt;div class=&quot;formcontainer&quot;&gt;
                  &lt;form ng-submit=&quot;ctrl.submit()&quot; name=&quot;myForm&quot; class=&quot;form-horizontal&quot;&gt;
                      &lt;input type=&quot;hidden&quot; ng-model=&quot;ctrl.user.id&quot; /&gt;
                      &lt;div class=&quot;row&quot;&gt;
                          &lt;div class=&quot;form-group col-md-12&quot;&gt;
                              &lt;label class=&quot;col-md-2 control-lable&quot; ><u>2. Server Part</u></h4>

As mentioned before, we can create a <strong>Spring REST API</strong> using <a href="http://websystique.com/springmvc/spring-mvc-4-restful-web-services-crud-example-resttemplate/">this post</a>. We need to adapt User properties based on User Interface in this example.

Complete Server is shown below.

<strong>Spring REST API controller</strong>: This Controller returns JSON response [thanks to Jackson library in classpath].



<strong>Service Interface</strong>



<strong>Service Implementation.</strong>


<strong>User Model class.</strong>



<strong>Spring Configuration Class.</strong>



<strong>Spring Initializer class.</strong>



<strong>CORS filter class</strong> : To handle <strong>Same Origin policy</strong> related issues.


<strong> Declare dependencies in pom.xml</strong>

&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;com.websystique.springmvc&lt;/groupId&gt;
  &lt;artifactId&gt;SpringMVC4RestAPI&lt;/artifactId&gt;
  &lt;packaging&gt;war&lt;/packaging&gt;
  &lt;version&gt;1.0.0&lt;/version&gt;
  &lt;name&gt;SpringMVC4RestAPI Maven Webapp&lt;/name&gt;

   &lt;properties&gt;
  &lt;springframework.version&gt;4.2.0.RELEASE&lt;/springframework.version&gt;
  &lt;jackson.version&gt;2.5.3&lt;/jackson.version&gt;
 &lt;/properties&gt;

 &lt;dependencies&gt;
  &lt;dependency&gt;
   &lt;groupId&gt;org.springframework&lt;/groupId&gt;
   &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
   &lt;version&gt;${springframework.version}&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
   &lt;groupId&gt;org.springframework&lt;/groupId&gt;
   &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;
   &lt;version&gt;${springframework.version}&lt;/version&gt;
  &lt;/dependency&gt;

  &lt;dependency&gt;
   &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
      &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
      &lt;version&gt;${jackson.version}&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
   &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
   &lt;artifactId&gt;javax.servlet-api&lt;/artifactId&gt;
   &lt;version&gt;3.1.0&lt;/version&gt;
  &lt;/dependency&gt;
   
 &lt;/dependencies&gt;


 &lt;build&gt;
  &lt;pluginManagement&gt;
   &lt;plugins&gt;
    &lt;plugin&gt;
     &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
     &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;
     &lt;version&gt;2.4&lt;/version&gt;
     &lt;configuration&gt;
      &lt;warSourceDirectory&gt;src/main/webapp&lt;/warSourceDirectory&gt;
      &lt;warName&gt;SpringMVC4RestAPI&lt;/warName&gt;
      &lt;failOnMissingWebXml&gt;false&lt;/failOnMissingWebXml&gt;
     &lt;/configuration&gt;
    &lt;/plugin&gt;
   &lt;/plugins&gt;
  &lt;/pluginManagement&gt;

  &lt;finalName&gt;SpringMVC4RestAPI&lt;/finalName&gt;
 &lt;/build&gt;
&lt;/project&gt;

Project Structure

Deploy & Run.

Build and Deploy Server to any Servlet 3 environment. I am using Tomcat 8 here. Then run the server using bin/startup.bat in Tomcat.

Open the FE (ServerExample.html) created above. You will see list of users.

Play with create/edit/delete users to see them in action. Open Developer Tools in your browser to see how client and server is communicating using JSON.

Live Demo

Please note that this live demo is showing only UI of your application, backed with static user data.There is no live JVM attached with this live demo. Refresh the page to repopulate with initial data.

That’s it. Complete source code for this post can be downloaded from Spring 4 MVC+AngularJS Example.

View Comments

  • Oh very good example. Thanks a lot. I expect an example to integrate app with social media like facebook..

  • Did find the solution myself, for welcome.jsp

    @RestController

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView sayHello(ModelMap model) {
    ModelAndView mav = new ModelAndView("welcome");
    return mav;
    }

  • Dear websystique,

    Is it possible to combine the usual @Controller with @RestController.
    If i put the contents of ServiceExample.html in a welcome.jsp, i just get the text welcome.jsp in the browser.

    Mark

  • First of all thanks for the post. It's nice and useful. I've got one question. What is the difference between the following two snippets:

    ...then(self.fetchAllUsers, function(errResponse)...);

    and

    ...then(self.fetchAllUsers(), function(errResponse)...);

    The second one has additional braces. I mean why do you use the first one, and why does the second one give wrong behavior?

    Thanks in advance!

    • Hi Stepan,

      In first case, we are passing the function 'fetchAllUsers' as callback, without executing it immediately. It will be executed at some point in time when certain condition met [successful response from server, which will eventually carry some data from server we can play with].

      In second case, we are executing it immediately. But this is not our goal, we want to execute it as a callback function only.

      Note that in first case, you could have written the complete body as well, but since 'fetchAllUsers' is used on several places, i preferred to put only the function name, and defined it somewhere else. Hope it's clear for you

    • Hi Cleison,

      This post consist of separate FE application & BE applications. It is deliberately done. FE application consist of just plain HTML with AngularJS, which is fully shown in this post. BE application is taken from from this post, also shown here with full code.

      If you prefer one single application consisting both parts (with download), please look at SpringMVC+AngularJS Example post.

Share
Published by

Recent Posts

Spring Boot + AngularJS + Spring Data + JPA CRUD App Example

In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…

8 years ago

Spring Boot Rest API Example

Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…

8 years ago

Spring Boot WAR deployment example

Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…

8 years ago

Spring Boot Introduction + hello world example

Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…

8 years ago

Secure Spring REST API using OAuth2

Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…

8 years ago

AngularJS+Spring Security using Basic Authentication

This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…

8 years ago