Please note that I already read all the StackOverflow questions that are somewhat related to my questions but none of these really answer my question. Please don't mark this as duplicate without fully understanding my question.
Here's my concern:
I would like to delay angularJS $http.get call without affecting the angular promise. Right now the code below throws a "angular-1.3.15.js:11655 TypeError: Cannot read property 'then' of undefined" in this line:
updatedPromise = promise.then(function(price)
Here's my partial code:
MyAPP.service('FirstService', ['$q','$http', 'Constants', 'SecondService', 'UtilityService', function($q, $http, Constants, SecondService, UtilityService) {
var self = this;
var processFunction = function(AnArray) {
var updatedPromise;
var promises=[];
angular.forEach(AnArray, function(itemObj, index)
{
var totalWorth = "";
if(itemObj.name != "")
{
var promise = SecondService.getPrice(itemObj.name);
updatedPromise = promise.then(function(price){
itemObj.price = price;
return itemObj;
}, function(error){
console.log('[+] Retrieving price has an error: ', error);
});
promises.push(updatedPromise);
}
else
{
console.log("Error!");
}
});
return $q.all(promises);
};
);
MyAPP.service('SecondService', ['$timeout','$http', 'Constants', function($timeout, $http, Constants) {
var self = this;
var URL = "/getPrice";
self.getPrice = function(itemName){
$timeout(function(){
var promise;
promise = $http({
url: URL,
method: 'POST',
data: {_itemName : itemName},
headers: {'Content-Type': 'application/json'}
}).then(function(response) {
return response.data;
}, function(response) {
console.log("Response: " + response.data);
return response.data;
});
return promise;
}, 3500);
console.log("[-]getPrice");
};
}]);
Please note that the processFunction should really return an array of promises because this is needed in other functions.
Your help will be highly appreciated!
Let me know for further questions/clarifications.
Thanks!
$timeout returns a promise, so you can return that, and then return the promise from $http:
self.getPrice = function (itemName) {
return $timeout(3500).then(function () {
return $http({
url: URL,
method: 'POST',
data: { _itemName: itemName },
headers: { 'Content-Type': 'application/json' }
});
}).then(function (response) {
return response.data;
}, function (response) {
console.log("Response: " + response.data);
return response.data;
});
};
Related
I get a value of "True" in my response. How come my debugger and alert and AccessGranted() in the .then of my $http is not being invoked. Below is my Script:
app.controller("LoginController", function($scope, $http) {
$scope.btnText = "Enter";
$scope.message = "";
$scope.login = function() {
$scope.btnText = "Please wait...";
$scope.message = "We're logging you in.";
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
}).then(function (response) {
debugger;
alert(response.data);
if (response.data == "True") {
AccessGranted();
} else {
$scope.message = response.data;
$scope.btnText = "Enter";
}
},
function (error) {
$scope.message = 'Sending error: ' + error;
});
}
$scope.AccessGranted = function() {
window.location.pathname("/Home/HomeIndex");
}
});
This is in my HomeController
public ActionResult HomeIndex()
{
var am = new AuditManager();
var auditModel = new AuditModel()
{
AccountId = 0,
ActionDateTime = DateTime.Now,
ActionName = "Home",
ActionResult = "Redirected to Home"
};
am.InsertAudit(auditModel);
return View("Index");
}
Please see image for the response I get.
seems like your approach is wrong
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Try this,
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
})
.then(function (response) {
console.log(response);
},
function (error) {
console.log(error);
});
And check your browser console for logs or any errors
Make sure the response is application/json content type, and content is json.
You can also write own httpProvider for check result from server
module.config(['$httpProvider', function ($httpProvider) {
...
I would suggest you to code like this instead of then so whenever there is success, The success part will be invoked.
$http.get('/path/').success(function (data) {
$scope.yourdata = data.data;
//console.log($scope.yourdata);
}).error(function (error){
//error part
});
i want to get just my service in the variable from my controller but it give me an $$state object
this is my controller
$scope.myDataSMS = ServiceSms.async().then(function(data){
$scope.myDataSMS1 = data;
console.log($scope.myDataSMS1);
return $scope.myDataSMS1;
});
console.log($scope.myDataSMS);
and my service
routeAppControllers.factory('ServiceSms', function($http,Token) {
var key = Token.CreateToken()
var myService = {
async: function() {
var data = 'token=' + encodeURIComponent(key);
var promise = $http({
method: 'POST',
url: 'PhpFunction/getsms.php',
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function(data) {
// The then function here is an opportunity to modify the response
// console.log(data.data);
// The return value gets picked up by the then in the controller.
return data.data;
})
// Return the promise to the controller
return promise;
}
};
return myService;
});
i think that the problems is with the promise but there i m little bit stuck
if someone can help me please
thanks in advance
this would be a better way to write your promise:
CONTROLLER:
.controller('nameofcontroller', ['$scope', 'ServiceSms', function($scope, ServiceSms) {
$scope.myDataSMS = ServiceSms.async()
.then(
function(data){
$scope.myDataSMS1 = data;
console.log($scope.myDataSMS1);
return $scope.myDataSMS1;
},
function(err){
console.log('err: ' + err);
});
}]);
SERVICE:
routeAppControllers.factory('ServiceSms', function($http,Token) {
return {
async: function() {
var data = 'token=' + encodeURIComponent(key);
return $http({
method: 'POST',
url: 'PhpFunction/getsms.php',
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
}
}
});
I have a Service which fetch the data from API.When I am trying to call this service. It's returning with same value.
appName.service('FetchCustomerDate', ['$http', '$q', function($http, $q) {
var self = this;
self.getCustomerData = function(token,name) {
var deferred = $q.defer();
return $http({
method: 'GET',
url: ,
headers: {
"Authorization": token,
"x-xcmc-auth": ''
}
}).then(function(response) {
deferred.resolve(response);
return deferred.promise;
}, function(response) {
deferred.reject(response);
return deferred.promise;
});
};
}]);
I see a bit of confusion here. Let's try to clear it. If you want to use deferred object, you need to change your code a bit:
appName.service('FetchCustomerDate', ['$http', '$q', function ($http, $q) {
var self = this;
self.getCustomerData = function (token, name) {
var deferred = $q.defer();
$http({ // Do not return here, you need to return the deferred.promise
method: 'GET',
url: '...some URL here...',
headers: {
"Authorization": token,
"x-xcmc-auth": ''
}
}).then(function (response) {
deferred.resolve(response); // It's correct, you are resolving the deferred promise here.
// return deferred.promise; // You do not need to return the deferred.promise here.
}, function (response) {
deferred.reject(response); // It's correct, you are rejecting the deferred promise here.
// return deferred.promise; // You do not need to return the deferred.promise here.
});
return deferred.promise; // The function must return the deferred.promise
};
}]);
In detail, function getCustomerData must return the promise belonging to deferred object with return deferred.promise. Inside then() callback you simply resolve or reject deferred promise. You do not need to return the deferred.promise.
You can improve the code. The $http service returns a promise, and the value returned by then callbacks is wrapped by then method in a promise. Knowing that, you can remove the use of deferred object:
appName.service('FetchCustomerDate', ['$http', function ($http) {
var self = this;
self.getCustomerData = function (token, name) {
return $http({ // Here, you need to return the promise returned by $http. Than promise will contain the response returned inside "then" callbacks.
method: 'GET',
url: '...some URL here...',
headers: {
"Authorization": token,
"x-xcmc-auth": ''
}
}).then(function (response) {
return response; // Simply return the response, it will be wrapped in a resolved promise by "then()"
}, function (response) {
return response; // Simply return the response, it will be wrapped in a rejected promise by "then()"
});
};
}]);
As you can see, the 2 then callbacks simply returns the response object, for this reason you can omit them:
appName.service('FetchCustomerDate', ['$http', function ($http) {
var self = this;
self.getCustomerData = function (token, name) {
return $http({ // Here, you need to return the promise returned by $http. Than promise will contain the response form the GET call
method: 'GET',
url: '...some URL here...',
headers: {
"Authorization": token,
"x-xcmc-auth": ''
}
});
};
}]);
Usually when you fetch data with the $httpservice, you want to obtain data from the response and affect it to the $scope for instance, or process it somehow. What are you trying to do? Please clarify your question.
Normally a fetch will look something like this:
appName.service('FetchCustomerDate', ['$http', '$q', function($http, $q) {
var self = this;
function notifyError(reason) {
console.error(reason);
}
self.getCustomerData = function(token,name) {
var deferred = $q.defer();
return $http({
method: 'GET',
url: ,
headers: {
"Authorization": token,
"x-xcmc-auth": ''
}
})
.then(function onSuccess(response) {
var cfg = response.data; // process data
})
.then(function onSuccess(response) {
// chained promises
})
.then(
function onSuccess(res) {
// ... this will trigger the chain reaction
deferred.resolve(res);
},
function onFailure(reason) {
notifyError(reason); // manage the error
deferred.reject(reason);
})
;
return deferred.promise;
}
}]);
This code fetches categories and give them to controller.
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function() {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
if ( SuperCategories.length == 0 ) {
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
});
}else {
return $q.when(SuperCategories);
}
}
return SCService;
});
I think code is perfect until there is no error in http request.
My query is how to do error handling (try catch or something like that), in case if server have some issue or may be cgi-script have some issue and not able to server the request.
Angular promises use a method catch for that.
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
});
You should use also finally :
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
}).finally(function() {
// Always executed. Clean up variables, call a callback, etc...
});
Write like
return $http(req).then(function (response) {
//success callback
},
function(){
//Failure callback
});
Use callback methods from controller Like
Controller.js
service.GetSuperCategories(function (data) {console.log('success'},function (error){console.log('error'});
service.js
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function(successMethod,errorMethod) {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
return $http(req).then(successMethod(data),
errorMethod(error));
}
return SCService;
});
You can use the .success and .error methods of $http service, as below
$http(req).success(function(data, status, headers){
// success callback: Enters if status = 200
}).error(function(status, headers){
// error callback: enters otherwise
});
myapp.factory('serviceName', function( $http, webStorage){
var factory = {};
var resoureurlBase=some base url;
factory.genericService = function(method, payload, methodName, callbackFn, callbackError, param) {
var httpRequest = null;
if (param && param == true) {
httpRequest = $http({
url: resoureurlBase+methodName,
method: method,
params: payload,
headers: {
'Content-Type': 'application/json'
}
});
} else {
httpRequest = $http({
url: resoureurlBase+methodName,
method: method,
data: payload,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
httpRequest.then(function(response) {
if (callbackFn && callbackFn.call) {
callbackFn.call(null, response);
}
},
function(response) {
if (callbackError && callbackError.call) {
callbackError.call(response);
}
});
httpRequest.error(function(data, status, headers, config) {
});
};
return factory;
});
/*
I have written service like above how can i handle in controller
i mean
how to write call back function in controller
how to inject
etc..
*/
Simple DI(dependency injection) it into your controller:-
myapp.controller('myCtrl',['$scope','serviceName',function($scope,serviceName){
// use serviceName to call your factory function
}]);
Ref:- https://docs.angularjs.org/guide/di
You need to call service like
serviceName.genericService(--parmas--).then(function(d){
//success
})
because from service serviceName, you're returning a promise that need to resolved using .then only.
Controller
var mainController = function($scope, serviceName) {
var callbackFn = function() {
console.log('Success');
}
var callbackError = function() {
console.log('Error');
}
var parameter = {
param1: 1
},
method = 'something', payload = 100, methodName = 'something';
serviceName.genericService(method, payload, methodName, callbackFn, callbackError, parameter).then(
//success function
function(data) {
//call after call succeed
},
//error function
function(error) {
//call after call error
});
};
myapp.controller('mainController', ['$scope', 'serviceName', mainController()];
Hope this could help you. Thanks.