Below is my code
MY_MODULE.factory("SOME_API", ['$resource', '$http', '$rootScope', function($resource, $http, $rootScope){
return $resource("/appi/get/", {responseFormat: 'json', responselanguage:'English', pageno:1}, {
search:{
method:'GET',
transformResponse: [function (data, headersGetter) {
console.log(data);
// you can examine the raw response in here
$log.info(data);
$log.info(headersGetter());
return {tada:"Check your console"};
}].concat($http.defaults.transformResponse),
params:{
param1:'SOME_DATA',
param2:'SOME_DATA2',
}
}
}
}
I m using angular 1.0.7, can't figure out why my transformResponse is not called. I believe this version of angular supports transformResponse, if not how to implement similar callback.
transformResponse is not a parameter to $resource. The response interceptor are configured on $httpProvider. See the documentation of $http (Section Response Interceptor).
Keep in mind that once configured these interceptors would run for each request that was made by $http.
Is it possible to use AngularJS 1.2?
I had the exact same problem with 1.0.8. After I changed to angular-1.2.0-rc.2, my resource's transformResponse callback started being called.
Below is the solution, basically a wrapper to $http, which emulates default resource
$rootScope.woiresource = function (url, defaults, actions) {
var $res = {};
for (var i in actions) {
var default_params = {};
for (var di in defaults) {
default_params[di] = defaults[di];
}
for (var ai in actions[i].params) {
default_params[ai] = actions[i].params[ai];
}
$res[i] = (function (url, method, default_params) {
return function (params, callback, headers) {
if (typeof params == 'function') {
callback = params;
params = {};
}
if (typeof headers == 'undefined') {
headers = {};
}
for (var pi in params) {
default_params[pi] = params[pi];
}
return $http({
url: url,
method: method,
transformResponse: [function (strData, headersGetter) {
//Do Something
}].concat($http.defaults.transformResponse),
params: default_params,
headers: headers,
}).success(function (data) {
callback(data);
});
};
})(url, actions[i].method, default_params);
}
return $res;
};
Parameters are similar to default resource just changed the working, hope this helps some people.
Related
I want to create a global variable (httpTimeout) initialize at the start, contains a Long value returned by a synchrone call Rest Service and used it in different service
(
function () {
'use strict';
angular
.module('module')
.factory('MyService', function (
$http,
$q
){
var service = {};
var httpTimeout = function() {
return $http({
method: 'GET', '.../rest/getHttpTimeOut'
}).then(function (response) {
return response.data;
}).catch(function (err) {
return 30000;
});
};
service.myService1= function (Model) {
return $http({
method: 'POST', '..../rest/callRestService1',
data: Model, timeout : httpTimeout
}).then(function (response) {
return response.data;
});
};
service.myService2= function (Model) {
return $http({
method: 'POST', '..../rest/callRestService2',
data: Model, timeout : httpTimeout
}).then(function (response) {
return response.data;
});
};});
My rest service
#RequestMapping(value = "/getHttpTimeOut", method = RequestMethod.GET)
#ResponseBody
public long getHttpTimeOutValue() {
return timeoutValue;
}
how i can retrieve this value globally (httpTimeout) for use in other services
Thank you for your help
if your question is how to do something on application start :
look at that
After your application start you can use another service to store the value.
Also if you want to apply this comportement for all request take a look to interceptor
I am trying to convert an Ajax call with WSSE authentication to an AngularJS factory.
The method is Post.
The intended use of this is to access the Adobe Analytics Rest API and return data to be converted to JSON and then visualised with d3.js.
I am not familiar with the properties that can be used in an AngularJS $http post call and so not sure what is the correct way to do the WSSE auth, dataType, callback etc.
This is the original ajax code which came from a public github repo:
(function($) {
window.MarketingCloud = {
env: {},
wsse: new Wsse(),
/** Make the api request */
/* callback should follow standard jQuery request format:
* function callback(data)
*/
makeRequest: function (username, secret, method, params, endpoint, callback)
{
var headers = MarketingCloud.wsse.generateAuth(username, secret);
var url = 'https://'+endpoint+'/admin/1.4/rest/?method='+method;
$.ajax(url, {
type:'POST',
data: params,
complete: callback,
dataType: "text",
headers: {
'X-WSSE': headers['X-WSSE']
}
});
}
};
})(jQuery);
This is the current way the code is being used with pure JS:
MarketingCloud.makeRequest(username, secret, method, params, endpoint, function(response) {
data = JSON.parse(response.responseText);
});
I want to convert this to a factory and a controller respectively.
This is what I have done for the factory so far:
app.factory('mainFactory', ['$http', function($http) {
var wsse = new Wsse ();
return function(username, secret, method, params, endpoint) {
return $http({
method: 'POST',
url: 'https://' + endpoint + '/admin/1.4/rest/?method=' + method,
data: params,
headers: {
'X-WSSE': wsse.generateAuth(username, secret)['X-WSSE']
},
dataType: 'text',
});
};
}]);
And this is what I have for the controller:
app.controller('mainController', ['$scope', 'mainFactory', function($scope, mainFactory) {
mainFactory.success(function(data) {
$scope.data = data;
});
}]);
Currently I get an error saying mainFactory.success is not a function which I assume is because the factory isn't working yet.
I have resolved this question myself. The parameters I was passing to the first function in the factory were globally defined already and therefore getting over-written.
The first function is not required anyway.
Here is the factory code:
app.factory('mainFactory', ['$http', function($http) {
var wsse = new Wsse ();
return {
getAnalytics : function (){
$http({
method: 'POST',
url: 'https://' + endpoint + '/admin/1.4/rest/?method=' + method,
data: params,
headers: {
'X-WSSE': wsse.generateAuth(username, secret)['X-WSSE']
}
})
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}
};
}]);
And here is the controller code:
app.controller('mainController', ['$scope', 'mainFactory', function($scope, mainFactory) {
$scope.title = "Inn Site";
$scope.data = mainFactory.getAnalytics();
}]);
I have created a below factory which is supposed to return some data based by taking url and an input paramenter as No.
(function () {
'use strict'
angular.module('MainApp').factory('GetData', ['$http', function ($http) {
return {
getCountries: function (url, No) {
return $http({
method: "GET",
url: url,
DNo: No,
});
}
}
}]);
})();
I have injected this factory to my controller and used as below.
GetData.getCountries('/General/API/GetDetails', $scope.No).then(function (res) {
console.log(res.data);
}, function (res) {
});
}
and here is my API.
public JsonResult GetDetails(string DNo)
{
var allCntry = entity.spGetCountries(DNo).ToList();
return Json(allCntry, JsonRequestBehavior.AllowGet);
}
All is good, the factory calls the api but does not send the parameter value, my API always set/initialized to null value.
To apply search parameters to a URL with the $http service, use the params property of the config:
angular.module('MainApp').factory('GetData', ['$http', function ($http) {
return {
getCountries: function (url, No) {
return $http({
method: "GET",
url: url,
//DNo: No,
//USE params property
params: { Dno: No }
});
}
}
}]);
config
- params – {Object.<string|Object>} – Map of strings or objects which will be serialized with the paramSerializer and appended as GET parameters.
-- AngularJS $http Service API Reference - Usage.
Use Case:
I want to create a service in angular which will return me a data object which is a variable inside service, which gets updated once via ajax call.
For first time till data is not received via ajax, it will return {}. Once data is received it will return that data always.
Issue:
The data is properly received in ajax. The structure of data received is an object. I have checked it by logging in console. But next time when this service is called it is again calling ajax as variable inside service is not getting updated.
Can anyone suggest why is this happening and what would be the idle way to achieve above ?
Code:
angular.module('myapp', []).service('TagService', function ($http, CONSTANTS) {
this.tagsData = {};
this.getTagsData = function (cacheMode) {
if (JSON.stringify(this.tagsData) != "{}") {
console.log("returning from cache");
return this.tagsData;
}
$http({
method: 'GET',
url: CONSTANTS['base_url_s'] + 'api/v1/get_all_tags_data/',
params: {'params': JSON.stringify({})}
}).success(
function (data, status, headers, config) {
if (data && data["success"] && data["success"] == true) {
this.tagsData = data["data"];
}
return this.tagsData;
}).error(
function (data, status, headers, config) {
return {};
});
};
});
You should not use this in your function. The this keyword is function scoped. You're not updating the same variable in your callback and in your first condition.
angular.module('myapp', []).service('TagService', function ($http, CONSTANTS) {
var tagsData = {};
this.getTagsData = function (cacheMode) {
if (JSON.stringify(tagsData) != "{}") {
console.log("returning from cache");
return tagsData;
}
$http({
method: 'GET',
url: CONSTANTS['base_url_s'] + 'api/v1/get_all_tags_data/',
params: {'params': JSON.stringify({})}
}).success(
function (data, status, headers, config) {
if (data && data["success"] && data["success"] == true) {
tagsData = data["data"];
}
return tagsData;
}).error(
function (data, status, headers, config) {
return {};
});
};
});
One more thing, you must use promise rather than returning your datas. Check the documentation about $q here.
The right way should be :
angular.module('myapp', []).service('TagService', function ($http, CONSTANTS, $q) {
var tagsData = {};
this.getTagsData = function (cacheMode) {
var defer = $q.defer();
if (JSON.stringify(tagsData) != "{}") {
console.log("returning from cache");
defer.resolve(tagsData);
}else{
$http({
method: 'GET',
url: CONSTANTS['base_url_s'] + 'api/v1/get_all_tags_data/',
params: {'params': JSON.stringify({})}
}).success(
function (data, status, headers, config) {
if (data && data["success"] && data["success"] == true) {
tagsData = data["data"];
}
return defer.resolve(tagsData);
}).error(
function (data, status, headers, config) {
return defer.reject({});
});
};
}
return defer.promise;
});
And then you should call:
TagService.getTagsData().then(function(yourTags){
// yourTags contains your data
});
I am trying to decorate the returned data from a angular $resource with data from a custom service.
My code is:
angular.module('yoApp')
.service('ServerStatus', ['$resource', 'ServerConfig', function($resource, ServerConfig) {
var mixinConfig = function(data, ServerConfig) {
for ( var i = 0; i < data.servers.length; i++) {
var cfg = ServerConfig.get({server: data.servers[i].name});
if (cfg) {
data.servers[i].cfg = cfg;
}
}
return data;
};
return $resource('/service/server/:server', {server: '#server'}, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(data, header) {
return mixinConfig(angular.fromJson(data), ServerConfig);
}
},
get: {
method: 'GET',
isArray: false,
transformResponse: function(data, header) {
var cfg = ServerConfig.get({server: 'localhost'});
return mixinConfig(angular.fromJson(data), ServerConfig);
}
}
});
}]);
It seems I am doing something wrong concerning dependency injection. The data returned from the ServerConfig.get() is marked as unresolved.
I got this working in a controller where I do the transformation with
ServerStatus.get(function(data) {$scope.mixinConfig(data);});
But I would rather do the decoration in the service. How can I make this work?
It is not possible to use the transformResponse to decorate the data with data from an asynchronous service.
I posted the solution to http://jsfiddle.net/maddin/7zgz6/.
Here is the pseudo-code explaining the solution:
angular.module('myApp').service('MyService', function($q, $resource) {
var getResult = function() {
var fullResult = $q.defer();
$resource('url').get().$promise.then(function(data) {
var partialPromises = [];
for (var i = 0; i < data.elements.length; i++) {
var ires = $q.defer();
partialPromisses.push(ires);
$resource('url2').get().$promise.then(function(data2) {
//do whatever you want with data
ires.resolve(data2);
});
$q.all(partialPromisses).then(function() {
fullResult.resolve(data);
});
return fullResult.promise; // or just fullResult
}
});
};
return {
getResult: getResult
};
});
Well, Its actually possible to decorate the data for a resource asynchronously but not with the transformResponse method. An interceptor should be used.
Here's a quick sample.
angular.module('app').factory('myResource', function ($resource, $http) {
return $resource('api/myresource', {}, {
get: {
method: 'GET',
interceptor: {
response: function (response) {
var originalData = response.data;
return $http({
method: 'GET',
url: 'api/otherresource'
})
.then(function (response) {
//modify the data of myResource with the data from the second request
originalData.otherResource = response.data;
return originalData;
});
}
}
});
You can use any service/resource instead of $http.
Update:
Due to the way angular's $resource interceptor is implemented the code above will only decorate the data returned by the $promise and in a way breaks some of the $resource concepts, this in particular.
var myObject = myResource.get(myId);
Only this will work.
var myObject;
myResource.get(myId).$promise.then(function (res) {
myObject = res;
});