Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to invoke Rest APIs from angularjs?

Tags:

angularjs

From where should REST API request be invoked from angular js?

I.e. from controller, module, service, factory. I am totally confused that what should be the right way for it?

like image 406
unknownbits Avatar asked Aug 30 '13 09:08

unknownbits


6 Answers

Here's what I would regard as best practice:

  • Use a factory service to handle the mechanics of access to the RESTful web api
  • Inject the factory service into the controller that needs access
  • Use a promise in the factory to resolve or reject the response from the $http call
  • The promise allows the controller to determine how it should respond to the result of the RESTful call. For example, it may want to invoke a toast popup to notify the user of any problem.

This maintains good separation between the data service layer, the business logic and the front-facing UI. It also limits any consequences of changes to any one layer, to other layers.

like image 137
John Kelleher Avatar answered Sep 28 '22 04:09

John Kelleher


You can use either resources, or build services that implement http calls.

If you want to use resources, remember:

  1. to include the angular-resource.js file which you can find here
  2. to include in your module declaration to include the ngResource module dependency like so: angular.module('myApp',['ngResource'])

After that you can declare a resource in this fashion:

function MyController($scope, $resource){
  var User = $resource('/user/:userId', {userId:'@id'});
  var user = User.get({userId:123}, function() {
    user.abc = true;
    user.$save();
  });
}

Alternatively, use services if you need a much deeper level of granularity such as

angular.module('myApp')
.factory('MyAPIService', function($http){
  var apiurl, myData;
  return {
    getData: function(){
      $http.get(apiurl)
      .success(function(data, status, config, headers){
        myData = data;
      })
      .error(function(){ //handler errors here
      });
    },
    data: function() { return myData; }
  };
});

I find services to be great because of the ability to share data between controllers, so you can inject them in a controller like so

myapp.controller('MyController', function($scope, MyAPIService){
  $scope.data = MyAPIService.data();
  // etc.

});
like image 41
Joe Minichino Avatar answered Sep 29 '22 04:09

Joe Minichino


This is how we do this, Write the http service as a factory method.

Edited as per comments to use Promise API

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

 MyApp .factory('ApiFactory', ['$http',
        function ($http) {
            return {
               getUsers: function (rowcount) {
                var promise = $http.get('api/Users/' + rowcount) .then(function(response) {
                return response.data;
              }, function (error) {
                //error
            })
            return promise;
           }
         }
       }
   ]);

Now you can use it in controller as this.

MyApp .controller('MyController', ['$scope', 'ApiFactory',
  function ($scope, ApiFactory) {

    $scope.Users = null;

    ApiFactory.getUsers(count).then(function(data)
    {
      $scope.Users = data;
    });
 } 
 ]);
like image 37
ssilas777 Avatar answered Sep 30 '22 04:09

ssilas777


You can use restangular https://github.com/mgonto/restangular

And you will call your api like that :

// Only stating main route
Restangular.all('accounts')

// Stating main object
Restangular.one('accounts', 1234)
like image 40
Tib Avatar answered Sep 29 '22 04:09

Tib


As long as you use the $http service it doesnt really make any difference

Although there is the provider methodology which states that you should have a data provider in the client side as well as the server side

For this matter I suggest a factory which exposes the methods you want and is utilizing the $http service itself

like image 40
Kia Panahi Rad Avatar answered Sep 27 '22 04:09

Kia Panahi Rad


If your going to use that REST API call in more than one controller it is best to create a service that is injected as a dependency into the controllers that need it. Like already mentioned, you want to use $resource to handle RESTful APIs.

index.html:

<!-- Include Angular and angular-resources -->
<script src="angular.js"></script>
<script src="angular-resource.js"></script>

<!-- Set up your angular module -->
<div ng-app="RESTfulServiceExample">
    <div ng-controller="HomeController">
        <ul>
            <li ng-repeat="game in games">{{game.GameName}}</li>
        </ul>
    </div>
</div>

<script>
    // Inject angular-resource as ngResource into your module
    var gameListApp = angular.module('RESTfulServiceExample', ['ngResource']);

    // Create a service to call API which can be used by many controllers
    gameListApp.factory('GameService', ['$resource', function($resource) {
        return $resource('/game/:gameId', {gameId: '@id'});
    }]);

    // Create a controller that uses your service
    gameListApp.controller('HomeController', function($scope, GameService) {
        // GET: /game/
        var games = GameService.query();

        // Use response in HTML template
        $scope.games = games;
    });

    // Another controller could use the same service
    gameListApp.controller('GameController', function($scope, GameService) {
        // use GameService for another purpose
    });
</script>

Reference: AngularJS: $resource

like image 32
Eric Wardell Avatar answered Sep 29 '22 04:09

Eric Wardell