简体   繁体   中英

Filter $http request data before it is sent

It seems Angular automatically strips properties prefixed with $$ , eg $$hashKey , from request data / params objects.

I would like to exclude my own UI-only properties that I don't want sent to the server, but of course I don't want to use $$ .

Does Angular expose their $$ filter method publicly in a way I can use it to filter my objects with a different prefix?

And, where would be the best place to use this (or a custom) method? A Transform? An Interceptor?

Lets say this is my data object:

var payload = {
    id: 12345,   
    name: 'Bob',
    _editing: true
};

And I save it to the server like this:

$http({
    method: 'POST',
    url: '/save',
    data: payload
});

How could I strip out the _editing property before the request is sent?

EDIT: Or any property starting with _

I need it to happen for all requests and it would need to work for deep, complex objects.

I'm using Angular v1.3.18

Thank you!

I would recommend using a http Interceptor

In your config you just put this line in the app.js

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

And I created a factory like this

.factory('httpInterceptor', ['$q', '$rootScope', '$filter', function ($q, $rootScope, $filter) {
    var canceller = $q.defer();
    //some vars here
    return {

        request: function (config) {


            //Do some magic here
            //modify the header for example
            config.headers.someHeader = something;
            //or set a timeout if it takes too long
            config.timeout = 20000;

            return config || $q.when(config)
        },

        response: function (response) {

            //handle Response if you want           
            return response || $q.when(response);
        },

        responseError: function (response) {

            //handle error here if you want
            return $q.reject(response);
        }
    };
}])

You can either access the config object and add or remove properties from the header or sent params or make a timeout and stuff, or access the response and do a broadcast or smth depends what you need

Hope this helps

Sure, use a $httpProvider.interceptors , but for the stripping part you can probably do something nice using lodash :

var o = {_f: 1, _b: 2, a: 1, b: 2 }

_.omit(o, function (value, key) { 
  return key.indexOf('_') === 0; 
});

This returns {a: 1, b: 2} .

But if you don't want to use an external library and just depend on Angular's utility kit, you could do:

angular.forEach(o, function (value, key) { 
  if (key.indexOf('_') === 0) { 
    delete o[key] 
  }
});

You can just delete the properties from the payload before you call the post .

var payload = {
    id: 12345,   
    name: 'Bob',
    _editing: true
};

delete payload._editing

$http({
    method: 'POST',
    url: '/save',
    data: payload
});

You should be using interceptors to modify your request or response. As the name itself suggests, its job is to intercept a http request or response. Quoted from angular documentation :

For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses, it is desirable to be able to intercept requests before they are handed to the server and responses before they are handed over to the application code that initiated these requests.

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

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

app.factory('myInterceptor', ['$q', function($q) {  

    var myInterceptor = {
        request: function(config) {
            delete config.data._editing;

            return config;
        }   
    };

    return myInterceptor;
}]);

app.controller('myController', ['$http', function($http) {
    var payload = {
        id: 12345,   
        name: 'Bob',
        _editing: true
    };

    $http({
        method: 'POST',
        url: '/echo/json/',
        data: payload
    });
}]);

I have prepared a working jsfiddle for that. The fiddle does the ajax request, so check the network tab to see the request payload.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM