Asked  7 Months ago    Answers:  5   Viewed   15 times

I recently posted a detailed description of the issue I am facing here at SO. As I couldn't send an actual $http request, I used timeout to simulate asynchronous behavior. Data binding from my model to view is working correct, with the help of @Gloopy

Now, when I use $http instead of $timeout (tested locally), I could see the asynchronous request was successful and data is filled with json response in my service. But, my view is not updating.

updated Plunkr here

 Answers

20

Here is a Plunk that does what you want: http://plnkr.co/edit/TTlbSv?p=preview

The idea is that you work with promises directly and their "then" functions to manipulate and access the asynchronously returned responses.

app.factory('myService', function($http) {
  var myService = {
    async: function() {
      // $http returns a promise, which has a then function, which also returns a promise
      var promise = $http.get('test.json').then(function (response) {
        // The then function here is an opportunity to modify the response
        console.log(response);
        // The return value gets picked up by the then in the controller.
        return response.data;
      });
      // Return the promise to the controller
      return promise;
    }
  };
  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  // Call the async method and then do stuff with what is returned inside our own then function
  myService.async().then(function(d) {
    $scope.data = d;
  });
});

Here is a slightly more complicated version that caches the request so you only make it first time (http://plnkr.co/edit/2yH1F4IMZlMS8QsV9rHv?p=preview):

app.factory('myService', function($http) {
  var promise;
  var myService = {
    async: function() {
      if ( !promise ) {
        // $http returns a promise, which has a then function, which also returns a promise
        promise = $http.get('test.json').then(function (response) {
          // The then function here is an opportunity to modify the response
          console.log(response);
          // The return value gets picked up by the then in the controller.
          return response.data;
        });
      }
      // Return the promise to the controller
      return promise;
    }
  };
  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  $scope.clearData = function() {
    $scope.data = {};
  };
  $scope.getData = function() {
    // Call the async method and then do stuff with what is returned inside our own then function
    myService.async().then(function(d) {
      $scope.data = d;
    });
  };
});
Tuesday, June 1, 2021
 
RenegadeAndy
answered 7 Months ago
20

So, my solution which works, using the new interceptor syntax is as follows:

// interceptors.js

.factory('httpRequestInterceptor', function ($q, $location) {
    return {
        'responseError': function(rejection) {
            // do something on error
            if(rejection.status === 404){
                $location.path('/404/');                    
            }
            return $q.reject(rejection);
         }
     };
});


// app.js

myApp.config( function ($httpProvider, $interpolateProvider, $routeProvider) {
    $httpProvider.interceptors.push('httpRequestInterceptor');

    $routeProvider
    ...
    .when('/404/:projectId', {
        templateUrl : 'partials/404.tmpl.html',
        controller: '404Ctrl',
        resolve: {
            project: function ($route) {
                // return a dummy project, with only id populated
                return {id: $route.current.params.projectId};
            }
        }
    });
});


// 404.tmpl.html

...

<h1>Oh No! 404.</h1> 
<p>Project with ID {{ project.id }} does not exist.</p>

This is a simplified version, but demonstrates how I used the interceptor pattern to solve my issue.

Comments are welcome.

Wednesday, September 8, 2021
 
heisenbergman
answered 3 Months ago
52

The reason you can't read the header on JavaScript but you can view it on the developer console is because for CORS requests, you need to allow the client to read the header.

Your server needs to send this header:

Access-Control-Expose-Headers:X-Total-Results

To answer your question in the comments, The Access-Control-Allow-Headers does not allow wildcards according to the W3 Spec

Tuesday, September 14, 2021
 
Twistar
answered 3 Months ago
70

A likely better method

If you don't want to get it inside a controller, you could have it injected into a recipe (ex, provider, factory, service): https://docs.angularjs.org/guide/providers

myApp.factory('getStuff', ['filter', '$http', function (filter, $http) {
    //Blah
}]);

If you want to get an instance of $http outside of any angular struct, you can do what's shown below.

The method given by Dennis works; however, it does not work if called before angular has been bootstrapped. Also, it seems like Derek has an error with Dennis' method because he does not have jquery.

The solution that Exlord mentioned is better, as it does not have that problem, and is more proper:

$http = angular.injector(["ng"]).get("$http");

Explained:

The angular injector is an:

object that can be used for retrieving services as well as for dependency injection

https://docs.angularjs.org/api/ng/function/angular.injector

The function angular.injector takes the modules as a parameter and returns an instance of the injector.

So in this case you retrieve an injector for the ng module (angular's), and then retrieve the service $http.

Note: One thing to keep in mind when using injector like this is that in my own findings it seems you need to make sure you include modules in the inject which what you are "getting" will need. For example:

angular.injector(['ng', 'ngCordova']).get('$cordovaFileTransfer')
Thursday, September 30, 2021
 
Peyton
answered 2 Months ago
43

Add following

httpWebRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

resulting in:

Talking to Web-Service: 6595
"Convert" stream to some useful data: 256

Now i have the same performance like in a browser!

Tuesday, October 5, 2021
 
Jeff Swensen
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share