Is it possible to cache some http until parameters used in url change:
app.factory('dataService', function ($http,$rootScope) {
return {
getData: function () {
return $http.get(rest.getData
+ $rootScope.number + "/" + $rootScope.blb
).then(function (result) {
return result.data;
});
}
}
});
So, when $rootScope.number changes in controller, I need to call http again, until then it should be cached. Is it possible and how?
Angular's $http has cache built in. Set cache as true in your $http request options:
$http.get(url, {cache: true}).then(...);
If you want to cache data you can do it in a number of ways.
You can cache it inside your service also.
Here is post which should help you.
Related
We are in the middle of converting our entire web infrastructure to use JWT as our Bearer auth tokens and I added a global interceptor on our $httpProvider that will read the token from a service that was previously (in a resolve for the root state of our app) fetched from our Auth server.
The problem is that I get a circular dependency because the initial call to GET /api/oauth/token uses the $http service which uses my interceptor. Therefore, the only way I think I can do this is to not use $http in that initial request, right?
What is the correct way to do this? It feels wrong to use jQuery here to make the AJAX call, but is that the best way?
app.factory('AuthProvider', function($http, $q){
var service = {};
var _token = null;
service.getToken = function(){
var deferred = $q.defer();
// the use of $http here is what causes this issue
$http({
method:'GET',
url:'/api/oauth/token'
}).then(function(res){
_token = res.result;
deferred.resolve(_token);
}, function(res){
deferred.reject(res);
});
return deferred.promise;
}
service.readToken = function(){
return _token;
}
return service;
});
i have developed single page application in angularjs. i have implemented the refresh token mechanism. refresh token suppose to refresh every 30 minutes. I am trying to handle refresh token in responseError of interceptor. I m trying to hold request if it returns 401 unauthorised error. Is there any mechanism to hold all the request once it return 401 error then refresh token and resume all request with new token.
Is it right way to handle the refresh token, here is sample code
$provide.factory('httpTokenInterceptor', function ($q, $injector, $cookies) {
return {
// On request sending
request: function (config) {
config.headers = config.headers || {};
// get this data from $cookies
var globals = $cookies.getObject('globals') || {};
//console.log(globals);
if (globals.authData)
config.headers.Authorization = 'Bearer ' + globals.authData.access_token;
return config;
},
// On response failure
responseError: function (rejection) {
console.log('AuthTokenHttpInterceptor responseError');
console.log(rejection);
if (rejection.status === 401) {
//hold current and all pending request
var aService = $injector.get('authenticationService');
aService.getRefreshToken().then(function(response) {
//need to resume all the request here
deferred.resolve(response);
});
return deferred.promise;
}
return $q.reject(rejection);
}
};
});
In short, you don't want to hold up any of your HTTP calls like that.
Your solution will go and refresh your token after one of your HTTP calls already failed. Also, just to be clear, your code is adding Authorization header even on HTTP calls that are getting resources like HTML templates. If you don't want to do this, then you should restrict that as well.
For one solution, check out this link. It doesn't use any particular library for handling JWT tokens, but you will have to create a wrapper around this implementation to use it wherever you need to do a HTTP call.
My suggestion (and personal preference when handling JWT tokens) is using the angular-jwt library. It's really easy to set up and you can check it out here.
There more complex libraries like auth0, which can do a lot of other stuff, and can be used in conjuction with angular-jwt library. Check out this link to see how to handle token refreshing both prior to a HTTP call and on page refresh.
Hope this helps.
You can hold requests and resume them using AngularJS Interceptors.
authInterceptor.$inject = ['$q', '$rootScope'];
function authInterceptor($q, $rootScope) {
return {
request: function(config) {
var deferred = $q.defer();
$rootScope.$watch('continue', function(value) {
if(value === true)
deferred.resolve(config);
});
return deferred.promise;
}
};
}
In the above example all of the requests hold until $rootScope.continue becomes true. Otherwise they will wait forever.
I'm trying to get a basic query going with the new V2 API and Angular in WordPress 4.4.1. Perhaps someone can help me understand why the URL, /wp-json/wp/v2/posts, gives a JSON response with a 404.
Browsing to that URL gives me JSON like this:
{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}
And here is the JavaScript I'm using to make that .GET
var base = 'http://localhost:8888/recruitler';
var posts = '/wp-json/wp/v2/posts';
var user = '/wp-json/wp/v2/users/'; // append user id
var s = '/wp-json/wp/v2/posts?filter[s]='; // append search term
// basic HTTP call with Angular
var app = angular.module('app', ['ngRoute'])
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( base+posts ).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;
});
});
UPDATE:
This must be a local environment issue. Live websites work just fine. I've tested and this issue persists on all my local WAMP and MAMP dev sites. Restarting the server and or checking this answer got it working.
the factory looks right, according to the rest-api docs you need pretty permalinks plugin as well in order to rest-api plugin use custom url rewrites https://wordpress.org/plugins/rest-api/installation/
Can I define global variables or functions that can be accessed by all of my Angular service modules?
For example, I have several services that make http requests to various endpoints of the same url root. I would like to be able to change this root.
My service modules look like this.
var host = 'http://my-api.com';
return {
get: function(id) {
return $http({
url: host + '/contacts/' + id,
method: 'GET'
});
},
...
switchHost: function(url){
host = url;
}
});
So I can call ContactService.switchHost('http://new-url') in my Controllers to update this particular Service.
I would like to have some sort of Root Service where I coul define host and switchHost globally.
Note: The use case here is that some of our clients will be accessing our company API, and others will be self-hosting their resources.
i suggest you to create an interceptor which will digest an angular value like this.
angular.module('...')
.value('HOST', 'http://www.fu.bar.com/')
.factory('InterceptorFactory', function (HOST) {
return {
request: function(config) {
config.url = HOST + config.url;
return config;
}
};
})
.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('InterceptorFactory');
}]);
Whenever you call the $http service, the factory will be called and will add your host.
If you want to update the host, you just need to inject in any block the value and update it.
Thanks for the responses. I just did something like this.
angular.module('app.services').factory('RootService', function($http) {
return {
switchHost: function(url){
this.host = url;
},
host: 'http://app.apiary-mock.com'
}
});
This way the client can just type in a url on the settings page and the root will change, which is what I want.
I am trying to set some customer headers in a service factory. Here is the code:
angular.module('clinicalApp').factory('encounterService', function ($resource) {
var EncounterService = $resource('http://localhost:port/v1/providers/:providerId', {providerId:'#id', port: ':8280'}, {
search: {
method: 'GET',
isArray: true,
headers: {
'RemoteUser': 'billybob'
}
}
});
return EncounterService;
});
Here is the code that calls the service.
angular.module('clinicalApp').controller('MainCtrl', function ($scope, encounterService) {
encounterService.search({
limit: 2000,
organizationId : '11110000'
});
});
When I use this resource and everything works fine, but the header is not set on the ajax call, so I get a 401 in return. What else do I have to do to set the headers? Thanks for the help.
I am sure the other answers I received work, but I did not want to use $http, I wanted to use $resource. To use resource with custom headers, I had to upgrade my Angular version. I did not look into the source code to find the reason why, and I don't know what version this functionality changed. Right now I am using v1.2.0-rc.2 and everything just worked. It took a few changed in the app config, namely I had to name ngRoute as a dependency to make the version work, but then I was able to use $resource like we are supposed to do.
Don't use run(), use config() with $httpProvider:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.common = {
'RemoteUser': 'billybob'
};
}])
clinicalApp.run(function($http) {
$http.defaults.headers.common["Content-Type"] = "application/json, charset=UTF-8";
});