Is it suitable to use $httpBackend in production to abstract data service requests?

StackOverflow https://stackoverflow.com/questions/21864578

  •  13-10-2022
  •  | 
  •  

문제

I have a data service in my application that is responsible for retrieving information for my controllers. This information might come from local storage, window or an ajax request. The problem I am facing is the $q promise responses don't look like $http responses.

    this.getContactDetails = function(data) {
        // The first time this method is called, we expect contact details to be preloaded on the page.
        // We want to read and return that object then remove it from the page so subsequent requests are to the server.
        if(typeof $window.preloadData.contact !== 'undefined') {
            var contactDetails = JSON.parse(JSON.stringify($window.preloadData.contact));
            delete $window.preloadData.contact;
            // Since the method call should always have the same return type, we manually create a deferred object and set the resolution using the $q service.
            var deferred = $q.defer();
            deferred.resolve(contactDetails);
            return deferred.promise;
        }
        var request = requests.contactDetails.get;
        return $http(request);
    };

The $q service does a nice job here but it resolves as the object it was given. I wouldn't really expect it to wrap the response. I know $httpBackend could accomplish this.

$httpBackend.whenGET(request).respond(contactDetails);

But the service is used in the MockE2E library and I doubt this was its intended use. I am not sure how to call this off afterwards or what would happen if I used it twice on the same request but I can figure out these questions. My other concern is that there doesn't seem to be a way to pass the same config object to $httpBackend as I do to $http. $httpBackend only accepts a method, url, body and headers, while $http config allows me to specify parameters.

Currently my work-around is simply to create and $http-like wrapper myself.

var contactDetails = JSON.parse(JSON.stringify({
    data: $window.preloadData.contact
}));

But I don't find this very elegant. Is there a better/correct way to do this?

도움이 되었습니까?

해결책

You can implement your storage layer as a $cacheFactory and add it to $httpProvider during the configuration phase.

From the docs:

When the cache is enabled, $http stores the response from the server in the specified cache. The next time the same request is made, the response is served from the cache without sending a request to the server.

Hence, if you provide your own implementation of a cache with the following methods:

  • {object} info() — Returns id, size, and options of cache.
  • {{*}} put({string} key, {*} value) — Puts a new key-value pair into the cache and returns it.
  • {{*}} get({string} key) — Returns cached value for key or undefined for cache miss.
  • {void} remove({string} key) — Removes a key-value pair from the cache.
  • {void} removeAll() — Removes all cached values.
  • {void} destroy() — Removes references to this cache from $cacheFactory.

You can return values read from localStorage, session cookies, etc. and they will be treated as there were data sent from the server, just without the AJAX request.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top