How can I extend the $http service in angular?
Asked Answered
C

2

6

Unfortunately, we're stuck running 1.2.26 (will upgrade to 1.2.28 when it's gemified).

In the meantime, how can I patch (heh) $http so that the short-hand patch method is available? I'm pretty new to the whole service/factory/module thing. I've done hours of searching and can't seem to figure it out.

myApp.factory('patchedHTTP', function($http, BasicService) {
  // $http['patch'] = function(url, data, config) {
  //   return $http(angular.extend(config || {}, {
  //     method: 'patch',
  //     url: url,
  //     data: data
  //   }));
  // };
  var extended = angular.extend(BasicService, {});
  extended.createShortMethodsWithData('patch');
  return extended;
});

Above is the best I've got... and it doesn't do anything XD

Clyburn answered 29/9, 2015 at 20:43 Comment(2)
Patch is already avaible: code.angularjs.org/1.2.27/docs/api/ng/service/$http#patchVulcanize
1.2.27 is not gemified yet :) just want to patch this one little bit versus the whole thing.Clyburn
T
3

The module.decorator has been added to the module API in version 1.4. That's why it is not working in 1.2.x.

Please find below a working demo or here at jsfiddle.

It took me a while to implement the patch method because I've missed to return the promise of $http. But now it should be working.

angular.module('patchDemo', [])
.config(function ($provide) {

    $provide.decorator('$http', function ($delegate) {
        // NOTE: $delegate is the original service
		$delegate.patch = function(url, data, config) {
            var paramsObj = angular.extend({}, config || {}, {
                method: 'PATCH',
                url: url,
                data: data
            });

            return $delegate(paramsObj);
        }
		
        return $delegate;
    });
})
.controller('MainController', MainController);

function MainController($http) {
    console.log($http.patch);
    //$http({method: 'PATCH', url: 'http://jsonplaceholder.typicode.com/posts/1', data: {title:'foo'}}); //>>>>>working long version of patch

    $http.patch('http://jsonplaceholder.typicode.com/posts/1', {
        title: 'foo'
    }).then(function(response) {
    	console.log(response);
    });

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.26/angular.js"></script>
<div ng-app="patchDemo" ng-controller="MainController"></div>
Thrift answered 29/9, 2015 at 22:19 Comment(0)
B
4

You can do this with an angular decorator.

A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. For more information you can check angular documentation.

Example:

var app = angular.module('app');
app.decorator('$http', function ($delegate) {
  // NOTE: $delegate is the original service

  $delegate.patch = function () {
    // do the implementation here
  };

  return $delegate;
});

// usage
app.controller('SomeController', function($http) {
    $http.patch();
});

You can keep this decorator until you upgrade to some newer version and than just safely delete it.

Beecham answered 29/9, 2015 at 20:54 Comment(6)
This is amazing. Thank you, you're quick! :)Clyburn
I'm having trouble figuring out when/where to run this code. It can't seem to find my app instance.Clyburn
Ok I figured it out. Had to use the config block. Do you want to update your answer to show this and then I'll select it as the answer :)Clyburn
var app should be your module where you want the decorator registered. Example: var app = angular.module('app');Beecham
Yea, I put it right under my app declaration, and no good. :/ had to put it in the config block.Clyburn
Interesting, I though I could bet on it working. But that is another issue that we need to solve, you can provide some more info about it. However, if it's fine for you to define it in the config phase then go with it. Thanks for mentioning that option.Beecham
T
3

The module.decorator has been added to the module API in version 1.4. That's why it is not working in 1.2.x.

Please find below a working demo or here at jsfiddle.

It took me a while to implement the patch method because I've missed to return the promise of $http. But now it should be working.

angular.module('patchDemo', [])
.config(function ($provide) {

    $provide.decorator('$http', function ($delegate) {
        // NOTE: $delegate is the original service
		$delegate.patch = function(url, data, config) {
            var paramsObj = angular.extend({}, config || {}, {
                method: 'PATCH',
                url: url,
                data: data
            });

            return $delegate(paramsObj);
        }
		
        return $delegate;
    });
})
.controller('MainController', MainController);

function MainController($http) {
    console.log($http.patch);
    //$http({method: 'PATCH', url: 'http://jsonplaceholder.typicode.com/posts/1', data: {title:'foo'}}); //>>>>>working long version of patch

    $http.patch('http://jsonplaceholder.typicode.com/posts/1', {
        title: 'foo'
    }).then(function(response) {
    	console.log(response);
    });

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.26/angular.js"></script>
<div ng-app="patchDemo" ng-controller="MainController"></div>
Thrift answered 29/9, 2015 at 22:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.