How to execute simultaneously an $http in angularjs - javascript

I have a module(app) which contains inside a service(globalService) with $http. This module now is included inside another module (invoicesApp) which has a service(invoicesService) too. Using the service of the second module I'm loading the service of the first service and returning back some information. The problem which I'm having is that the parameters of the first service are overridden from the second service and for that reason both $http are executing the same request. Here is my code
This is my first Service:
(function(angular){
var app = angular.module('app',[])
.config(function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
})
.service('globalService', function($http, $location,$q){
console.log("globalService");
this.getPaging = function()
{
var deferred = $q.defer();
var paging_parameters = $location.search();
paging_parameters.action = "client_pagination";
var req = {
url: ajaxpagingscript.ajaxurl,
method: "GET",
params: paging_parameters
}
$http(req).success(function(paging_data) {
console.log("globalService " + JSON.stringify(paging_data));
deferred.resolve(paging_data.paging);
}).error(function(data, status, headers)
{
$scope.error = "";
});
return deferred.promise;
}
});
})(window.angular);
Second Service:
(function(angular){
var invoicesApp = angular.module('invoicesApp',['ngRoute','app'])
.config(function($locationProvider,$routeProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
})
.controller('InvoicesController', ['$scope','transactionService',
function($scope,invoicesService) {
$scope.invoices = [];
console.log("testing");
var paging = invoicesService.getPaging();
var promise = invoicesService.getInvoicess();
promise.then(function(data)
{
console.log("invoices " +JSON.stringify(data));
angular.forEach(data.new_data, function(JSON_ARRAY) {
$scope.invoicearray.push(JSON_ARRAY);
});
});
}])
.service('invoicesService', function(globalService, $http,$location,$q){
this.getPaging = function() { return globalService.getPaging(); };
this.getInvoicess = function() {
var deferred = $q.defer();
var invoices_parameters = $location.search();
invoices_parameters.action = "collect_invoice_data";
var req = {
url: ajaxpagingscript.ajaxurl,
method: "GET",
params: invoices_parameters
};
$http(req).success(function(data) {
deferred.resolve(data);
}).error(function(data, status, headers)
{
$scope.error = "";
});
return deferred.promise;
};
});
})(window.angular);
The console.log for both services, returning back the same data. The page that loads this app, loads invoicesApp so the globalService is executed fine but the parameters that pass to $http are wrong. Can anyone help me?

You don't need to call the function, you need to pass the reference of the function if that is what you are trying to do in invoicesService.
this.getPaging = function() { return globalService.getPaging(); };
should be
this.getPaging = globalService.getPaging;

Related

How to call nest factory in Angularjs?

Hi I am developing web application in angularjs. I have requirement below. I have one factory. I have added code snippet below.
myapp.factory('sadadpaymentapi', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', 'leaselisting', function ($http, $cookieStore, cfg, ScrollFunction, leaselisting) {
var sadadpaymentapiobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var urlapi = baseurl + "api/ServiceRequest/CreateRSSedad/";
sadadpaymentapiobject.callsadad = function (PaymentType) {
leaselisting.leaselisting().then(function (response) {
//Problem in calling
}, function (error) { });
var request = {
url: urlapi,
method: 'POST',
data: {
SRActivityID: LoginID,
PaymentType: PaymentType,
PaymentAmount: "100"
},
headers: ScrollFunction.getheaders()
};
return $http(request);
}
return sadadpaymentapiobject;
}]);
Here is my second factory leaselisting
myapp.factory('leaselisting', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', function ($http, $cookieStore, cfg, ScrollFunction) {
var leaselistingobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
leaselistingobject.leaselisting=function(){
var requestObj = {
url: "api/ServiceRequest/GetROLSPSRLeaseList/",
data: {
LoginID: LoginID,
RSAccountNumber: $cookieStore.get("AccountNumber")
},
headers: ScrollFunction.getheaders()
};
$http(requestObj).then(function (response) {
}, function (error) {
});
}
return leaselistingobject;
}]);
I have found error in below line
leaselisting.leaselisting().then(function (response) { //Problem in calling
}, function (error) { });
May i am i doing anything wrong in the above code? May i know is it possible to call one factory from another? The response i get from leaselisting i want to pass it in callsadad function of sadadpaymentapi. So can someone hep me in the above code? I am getting error Cannot read property 'then' of undefined in the leaselisting.leaselisting().then(function (response) {},function(error){});
Also is there any way I can directly inject factory like payment amount: inject factory something like this?
I assume, that leaselistingobject.getValue is an asynchronous function.
So first of get your value :
leaselistingobject.getValue = function(){
var requestObj = {
url: "api/ServiceRequest/getValue/"
};
return $http(requestObj).then(function (response) {
return response.data;
});
}
And then use it. To let all async actions finish we use angulars $q.Here you can find a small tutorial.
myapp.factory('sadadpaymentapi', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', 'leaselisting', '$q',function ($http, $cookieStore, cfg, ScrollFunction, leaselisting, $q) {
var sadadpaymentapiobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var urlapi = baseurl + "api/ServiceRequest/CreateRSSedad/";
sadadpaymentapiobject.callsadad = function (PaymentType) {
var leastListingPromise = leaselisting.leaselisting();
var getValuePromise = leaselisting.getValue();
$q.all([leastListingPromise, getValuePromise]).then(function (responses) {
//Here you have both responses in an array
var request = {
url: urlapi,
method: 'POST',
data: {
SRActivityID: LoginID,
PaymentType: PaymentType,
PaymentAmount: responses[1]
},
headers: ScrollFunction.getheaders()
};
return $http(request);
});
}
return sadadpaymentapiobject;
}]);
To make leaselisting() return the response of the request change the end of the function from
$http(requestObj).then(function (response) {
}, function (error) {
});
to
return $http(requestObj).then(function (response) {
return response.data;
}, function (error) {
});
If wont do anything about possible errors you can omit the error function part:
return $http(requestObj).then(function (response) {
return response.data;
});

refresh an array without refreshing the page in angularJS

I have an array that I want to affect to it data that I have get from my Factory,but when I try to access it I don't get the data recently added to it,this the array when I try to fill it whith data:
$scope.copyofOpList = [];
$scope.UpdateOperations = function() {
$scope.copyofOpList = gammeOfFactory.getListOperations();
}
this is my Factory from which I get the Data:
.factory(
'gammeOfFactory',
function($http, $q) {
var backObject = {
getListOperations: _getListOperations
}
return backObject;
//used to get list of operations from ws
function _getListOperations() {
var defer = $q.defer();
$http({
method: "GET",
url: "MyWebService/getAll"
}).then(function mySucces(response) {
defer.resolve(response.data);
}, function myError(response) {
deferred.reject('Erreur into url ' + response);
});
return defer.promise;
};
});
so please,how can I refresh the Data in this array without refreshing the web page
thanks for help

AngularJS: transform response in $resource using a custom service

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;
});

How to use HTTP.GET in AngularJS correctly? In specific, for an external API call?

I have the following code in the controller.js,
var myApp = angular.module('myApp',[]);
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
$http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
return data
}).error(function(){
alert("error");
});
}
});
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = dataService.getData();
});
But, I think I m probably making a mistake with CORS related issue. Can you please point me to the correct way to make this call? Thanks much!
First, your success() handler just returns the data, but that's not returned to the caller of getData() since it's already in a callback. $http is an asynchronous call that returns a $promise, so you have to register a callback for when the data is available.
I'd recommend looking up Promises and the $q library in AngularJS since they're the best way to pass around asynchronous calls between services.
For simplicity, here's your same code re-written with a function callback provided by the calling controller:
var myApp = angular.module('myApp',[]);
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(callbackFunc) {
$http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
// With the data succesfully returned, call our callback
callbackFunc(data);
}).error(function(){
alert("error");
});
}
});
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData(function(dataResponse) {
$scope.data = dataResponse;
});
});
Now, $http actually already returns a $promise, so this can be re-written:
var myApp = angular.module('myApp',[]);
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
// $http() returns a $promise that we can add handlers with .then()
return $http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
});
}
});
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData().then(function(dataResponse) {
$scope.data = dataResponse;
});
});
Finally, there's better ways to configure the $http service to handle the headers for you using config() to setup the $httpProvider. Checkout the $http documentation for examples.
I suggest you use Promise
myApp.service('dataService', function($http,$q) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
deferred = $q.defer();
$http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
// With the data succesfully returned, we can resolve promise and we can access it in controller
deferred.resolve();
}).error(function(){
alert("error");
//let the function caller know the error
deferred.reject(error);
});
return deferred.promise;
}
});
so In your controller you can use the method
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData().then(function(response) {
$scope.data = response;
});
});
promises are powerful feature of angularjs and it is convenient special if you want to avoid nesting callbacks.
No need to promise with $http, i use it just with two returns :
myApp.service('dataService', function($http) {
this.getData = function() {
return $http({
method: 'GET',
url: 'https://www.example.com/api/v1/page',
params: 'limit=10, sort_by=created:desc',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
}).success(function(data){
return data;
}).error(function(){
alert("error");
return null ;
});
}
});
In controller
myApp.controller('AngularJSCtrl', function($scope, dataService) {
$scope.data = null;
dataService.getData().then(function(response) {
$scope.data = response;
});
});
Try this
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
Just setting useXDomain = true is not enough. AJAX request are also send with the X-Requested-With header, which indicate them as being AJAX. Removing the header is necessary, so the server is not rejecting the incoming request.
So you need to use what we call promise. Read how angular handles it here, https://docs.angularjs.org/api/ng/service/$q. Turns our $http support promises inherently so in your case we'll do something like this,
(function() {
"use strict";
var serviceCallJson = function($http) {
this.getCustomers = function() {
// http method anyways returns promise so you can catch it in calling function
return $http({
method : 'get',
url : '../viewersData/userPwdPair.json'
});
}
}
var validateIn = function (serviceCallJson, $q) {
this.called = function(username, password) {
var deferred = $q.defer();
serviceCallJson.getCustomers().then(
function( returnedData ) {
console.log(returnedData); // you should get output here this is a success handler
var i = 0;
angular.forEach(returnedData, function(value, key){
while (i < 10) {
if(value[i].username == username) {
if(value[i].password == password) {
alert("Logged In");
}
}
i = i + 1;
}
});
},
function() {
// this is error handler
}
);
return deferred.promise;
}
}
angular.module('assignment1App')
.service ('serviceCallJson', serviceCallJson)
angular.module('assignment1App')
.service ('validateIn', ['serviceCallJson', validateIn])
}())
Using Google Finance as an example to retrieve the ticker's last close price and the updated date & time. You may visit YouTiming.com for the run-time execution.
The service:
MyApp.service('getData',
[
'$http',
function($http) {
this.getQuote = function(ticker) {
var _url = 'https://www.google.com/finance/info?q=' + ticker;
return $http.get(_url); //Simply return the promise to the caller
};
}
]
);
The controller:
MyApp.controller('StockREST',
[
'$scope',
'getData', //<-- the service above
function($scope, getData) {
var getQuote = function(symbol) {
getData.getQuote(symbol)
.success(function(response, status, headers, config) {
var _data = response.substring(4, response.length);
var _json = JSON.parse(_data);
$scope.stockQuoteData = _json[0];
// ticker: $scope.stockQuoteData.t
// last price: $scope.stockQuoteData.l
// last updated time: $scope.stockQuoteData.ltt, such as "7:59PM EDT"
// last updated date & time: $scope.stockQuoteData.lt, such as "Sep 29, 7:59PM EDT"
})
.error(function(response, status, headers, config) {
console.log('### Error: in retrieving Google Finance stock quote, ticker = ' + symbol);
});
};
getQuote($scope.ticker.tick.name); //Initialize
$scope.getQuote = getQuote; //as defined above
}
]
);
The HTML:
<span>{{stockQuoteData.l}}, {{stockQuoteData.lt}}</span>
At the top of YouTiming.com home page, I have placed the notes for how to disable the CORS policy on Chrome and Safari.
When calling a promise defined in a service or in a factory make sure to use service as I could not get response from a promise defined in a factory. This is how I call a promise defined in a service.
myApp.service('serverOperations', function($http) {
this.get_data = function(user) {
return $http.post('http://localhost/serverOperations.php?action=get_data', user);
};
})
myApp.controller('loginCtrl', function($http, $q, serverOperations, user) {
serverOperations.get_data(user)
.then( function(response) {
console.log(response.data);
}
);
})

AngularJS defer did'n return variable

I not understand why my function does not set my global variable. My code:
var localizeRegForm = {};
var handlerLocalDef = function(defer) {
var hash;
defer.then(
function(response) {
return hash = response.data;
},
function(err) {
showPopup(err);
}
);
return hash;
};
var initialized = function() {
console.log("localizeRegForm",localizeRegForm);
localizeRegForm = handlerLocalDef(Localization.getLocalizedDefer('regularform'));
console.log("localizeRegForm",localizeRegForm)
}
My console show:
localizeRegForm Object {}
localizeRegForm undefined
it's better to rewrite it:
var initialized = function() {
Localization.getLocalizedDefer('regularform').then(function(response){
localizeRegForm = response.data;
console.log("localizeRegForm",localizeRegForm)
});
}
and the question is not about AngularJS,
it's more about using defered object
use it like this
var deferred = $q.defer();
$http({
method: 'POST',
url: 'something',
data: data
}).
success(function(response, status, headers, config) {
deferred.resolve(response);
}).
error(function(response, status, headers, config) {
deferred.reject("");
})
return deferred.promise;

Categories

Resources