Http Promise not resolving in controller - angularjs

I am just beginning to learn AngularJS and have a problem understanding promises. I have
factory which makes call to back-end server and returns a promise as follows:
var commonModule = angular.module("CommonModule", [])
.factory('AjaxFactory', function($http, $q, $dialogs, transformRequestAsFormPost) {
return {
post: function(reqUrl, formData) {
var deferred = $q.defer();
$http({
method: "post",
url: reqUrl,
transformRequest: transformRequestAsFormPost,
data: formData
}).success(function(data) {
if (data['error']) {
if (data['message']) {
$dialogs.notify('Error', data['message']);
} else {
}
} else if (data['success']) {
if (data['message']) {
$dialogs.notify('Message', data['message']);
}
} else if (data['validation']) {
}
deferred.resolve(data);
}).error(function(data) {
$dialogs.notify('Error', 'Unknown Error. Please contact administrator');
});
return deferred.promise;
}
};
})
.factory("transformRequestAsFormPost", function() {
function transformRequest(data, getHeaders) {
var headers = getHeaders();
headers[ "Content-type" ] = "application/x-www-form-urlencoded; charset=utf-8";
return(serializeData(data));
}
return(transformRequest);
function serializeData(data) {
if (!angular.isObject(data)) {
return((data === null) ? "" : data.toString());
}
var buffer = [];
for (var name in data) {
if (!data.hasOwnProperty(name)) {
continue;
}
var value = data[ name ];
buffer.push(
encodeURIComponent(name) +
"=" +
encodeURIComponent((value === null) ? "" : value)
);
}
var source = buffer
.join("&")
.replace(/%20/g, "+")
;
return(source);
}
}
);
I have a controller which calls the AjaxFactory service using two functions as follows
marketingCampaignModule.controller('CampaignInfoController', ['$scope', 'AjaxFactory', '$state', 'campaign', function($scope, AjaxFactory, $state, campaign) {
$scope.init = function() {
$scope.name = campaign['name'];
$scope.description = campaign['description'];
console.log($scope.mcmcid);
if ($scope.mcmcid > 0) {
var inputData = {};
inputData['mcmcid'] = $scope.mcmcid;
var ajaxPromise1 = AjaxFactory.post('index.php/mcm/infosave/view', inputData);
ajaxPromise1.then(function(data) {
if (data['success']) {
$scope.name = data['params']['name'];
$scope.description = data['params']['description'];
}
},
function(data) {
if (data['success']) {
$scope.name = data['params']['name'];
$scope.description = data['params']['description'];
}
}
);
}
};
$scope.init();
$scope.submitForm = function(isValid) {
if (isValid) {
var formData = $scope.prepareFormData();
var ajaxPromise = AjaxFactory.post('index.php/mcm/infosave/save', formData);
ajaxPromise.then(function(data) {
if (data['success']) {
$scope.setValues(data['params']);
} else if ('validation') {
$scope.handleServerValidationError(data['message']);
}
});
}
};
$scope.prepareFormData = function() {
mcmcId = '';
var formData = {};
if ($scope.mcmcid > 0) {
mcmcId = $scope.mcmcid;
}
formData["mcmcid"] = mcmcId;
formData["name"] = $scope.name;
formData["description"] = $scope.description;
return formData;
};
$scope.setValues = function(data) {
$scope.mcmcid = data['mcmcid'];
$state.go('TabsView.Companies');
};
$scope.handleServerValidationError = function(validationMessages) {
alert(validationMessages['name']);
};
}]);
The promise ajaxPromise gets resolved in the function $scope.submitform but not in $scope.init.
Please tell me what am I missing.

add to your service deffere.reject() on error:
app.factory('AjaxFactory', function($http, $q, $dialogs, transformRequestAsFormPost) {
return {
post: function(reqUrl, formData) {
var deferred = $q.defer();
$http({
method: "post",
url: reqUrl,
transformRequest: transformRequestAsFormPost,
data: formData
}).success(function(data) {
if (data['error']) {
if (data['message']) {
$dialogs.notify('Error', data['message']);
} else {
}
} else if (data['success']) {
if (data['message']) {
$dialogs.notify('Message', data['message']);
}
} else if (data['validation']) {
}
deferred.resolve(data);
}).error(function(data) {
deferred.reject(data)
$dialogs.notify('Error', 'Unknown Error. Please contact administrator');
});
return deferred.promise;
}
};
});
and in you controller handle error:
$scope.init = function () {
$scope.name = campaign['name'];
$scope.description = campaign['description'];
console.log($scope.mcmcid);
if ($scope.mcmcid > 0) {
var inputData = {};
inputData['mcmcid'] = $scope.mcmcid;
var ajaxPromise1 = AjaxFactory.post('index.php/mcm/infosave/view', inputData);
ajaxPromise1.then(function (data) {
if (data['success']) {
$scope.name = data['params']['name'];
$scope.description = data['params']['description'];
}
},
function (data) {
if (data['success']) {
$scope.name = data['params']['name'];
$scope.description = data['params']['description'];
}
},
//on error
function (data) {
alert("error");
console.log(data);
});
}
};

Related

AngularJS executing a function asynchronously

I have a controller that passes execution to a factory -- controller.getCustomerById -> factory.getCustomerByID. In this case, the factory function is posting and retrieving data via MVC/angular.$http.post. That all works fine but the subsequent actions in my controller function are executing before the .post is finished.
I've tried making either or both async/await but I think I'm not understanding how to do that. I've tried quite a few of the examples here and elsewhere with no luck.
I have a button that calls setOrderFromGrid which calls getCustomerById. I would assume that making controller.getCustomerById an async function would be the best way but I can't get it to work.
angular.module('aps').factory('TechSheetFactory',
function($http) {
return {
//The ajax that is called by our controller
ITS: function(onSuccess, onFailure) {
const rvtoken = $("input[name='__RequestVerificationToken']").val();
$http({
method: "post",
url: "/DesktopModules/MVC/TechSheetMaint/TechSheet/InitializeNew",
headers: {
"ModuleId": moduleId,
"TabId": tabId,
"RequestVerificationToken": rvtoken
}
}).then(onSuccess).catch(onFailure);
},
saveTechSheetAng: function(onSuccess, onFailure, techSheetInfo) {
alert(JSON.stringify(techSheetInfo));
const rvtoken = $("input[name='__RequestVerificationToken']").val();
$http.post("/DesktopModules/MVC/TechSheetMaint/TechSheet/SaveTechSheetAng",
JSON.stringify(techSheetInfo),
{
headers: {
"ModuleId": moduleId,
"TabId": tabId,
"RequestVerificationToken": rvtoken,
'Content-Type': 'application/json'
}
}).then(onSuccess).catch(onFailure);
} ,
getCustomerById: function(onSuccess, onFailure, customerSearchString) {
alert('factory getcustomerbyid: ' + customerSearchString);
const rvtoken = $("input[name='__RequestVerificationToken']").val();
$http.post("/DesktopModules/MVC/TechSheetMaint/TechSheet/GetCustomerById",
{custId:customerSearchString},
{
headers: {
"ModuleId": moduleId,
"TabId": tabId,
"RequestVerificationToken": rvtoken,
'Content-Type': 'application/json'
}
}).then(onSuccess).catch(onFailure);
}
};
});
angular.module('aps').controller('TechSheetCtl', ['TechSheetFactory','$scope', '$rootScope', '$http', '$interval', '$modal', '$log','uiGridConstants',
function (TechSheetFactory,$scope, $rootScope, $http, $interval, $modal, $log) {
/* -----------------SaveTechSheet ------------*/
$scope.saveTechSheet = function() {
if (!$scope.dvTechSheet.$valid) {
$scope.Message = "Form not complete.";
$scope.Status = false;
$scope.showErrors=true;
return;
}
alert($scope.TechSheetInfo.Customer.CustomerID);
if (JSON.stringify($scope.TechSheetInfo.Customer) !== JSON.stringify($scope.TechSheetInfoStatic.Customer) &&
$scope.TechSheetInfo.Customer.CustomerID !== 0) {
if (confirm("You've made changes to this Customer. Save them?") !== true) {
return;
}
}
if (JSON.stringify($scope.TechSheetInfo.WorkOrder) !== JSON.stringify($scope.TechSheetInfoStatic.WorkOrder) &&
$scope.TechSheetInfo.WorkOrder.WorkOrderID !== 0) {
if (confirm("You've made changes to this Work Order. Save them?") !== true) {
return;
}
}
successFunction = function(response) {
var data = response.data.Data;
alert(data);
var techSheet = data.techSheet;
alert(data.status);
if (data.status) {
alert("looks good");
$scope.Message = "";
$scope.showErrors = false;
$scope.TechSheetInfo = techSheet;
alert($scope.TechSheetInfo);
$scope.TechSheetInfoStatic = angular.copy(techSheet);
$rootScope.customerInfo = techSheet.Customer;
createpdf($scope);
} else {
if (response.message !== null) {
$scope.Status = datae.status;
$scope.showErrors = true;
$scope.Message = data.message;
}
}
};
failureFunction = function(data) {
console.log('Error' + data);
};
TechSheetFactory.saveTechSheetAng(successFunction, failureFunction,$scope.TechSheetInfo);
};
/* ----------End SaveTechSheet ---------*/
//------------Initialize a new tech sheet. This is the default action for the page load/refresh/discard changes/clear form
$scope.initializeTechSheet = function() {
$scope.TechSheetInfo = [];
$scope.TechSheetInfoStatic = [];
$scope.customerIDDisabled = false;
$scope.orderIDDisabled = false;
$rootScope.customerInfo = [];
$scope.WindowsPassword = "";
$scope.EmailPassword = "";
const successFunction = function(response) {
$scope.TechSheetInfo = response.data;
$rootScope.customerInfo = response.data.Customer;
$scope.TechSheetInfoStatic = angular.copy(response.data);
};
const failureFunction = function(response) {
//console.log('Error' + response.status);
};
TechSheetFactory.ITS(successFunction, failureFunction);
};
//end initializeTechSheet
$scope.getCustomerById = function(custId) {
const successFunction = function(response) {
alert("success");
$scope.TechSheetInfo.Customer = response.data;
$scope.TechSheetInfoStatic.Customer = angular.copy(response.data);
$rootScope.customerInfo = response.data;
$scope.customerIDDisabled = true;
};
const failureFunction = function(data) {
alert('getcustomer fail');
console.log('Error' + JSON.stringify(data));
};
TechSheetFactory.getCustomerById(successFunction, failureFunction, custId);
};
$scope.setOrderFromGrid = function(woInfo) {
$scope.getCustomerById(woInfo.CustomerID);
$scope.TechSheetInfo.WorkOrder = woInfo; //this line and the next are occurring before getCustomerById has completed
$scope.TechSheetInfoStatic.Customer = angular.copy($scope.TechSheetInfo.Customer);
$scope.orderIDDisabled=true;
$scope.dvTechSheet.$setPristine();
};
$scope.resetForm = function() {
if (!$scope.dvTechSheet.$pristine) {
if (!confirm("Discard Changes?")) {
return;
}
}
$scope.initializeTechSheet();
$scope.dvTechSheet.$setPristine();
};
}]);
You lose the advantage of the Promises so you can opt-in a Promise this way. (I do not recommend it)
From the top of head something like this:
// inject $q
$scope.getCustomerById = function(custId) {
const deferred = $q.defer()
const successFunction = function(response) {
$scope.TechSheetInfo.Customer = response.data;
$scope.TechSheetInfoStatic.Customer = angular.copy(response.data);
$rootScope.customerInfo = response.data;
$scope.customerIDDisabled = true;
deferred.resolve(); // can pass value if you like
};
const failureFunction = function(data) {
alert('getcustomer fail');
console.log('Error' + JSON.stringify(data));
deferred.reject();
};
TechSheetFactory.getCustomerById(successFunction, failureFunction, custId);
return deferred.promise;
};
/////////////
$scope.setOrderFromGrid = function(woInfo) {
const prom = $scope.getCustomerById(woInfo.CustomerID);
prom.then(()=>{
$scope.TechSheetInfo.WorkOrder = woInfo;
$scope.TechSheetInfoStatic.Customer =
angular.copy($scope.TechSheetInfo.Customer);
$scope.orderIDDisabled=true;
$scope.dvTechSheet.$setPristine();
})
};

angular service modal not closing properly & calling multiple times

Mentioned on the github repository #225 of angular-service-modal
But i don't have a $on on $rootScope, so that shouldn't be the problem.
(also included code below)
My modal is getting called multiple times on close/hiding. Eg. [http://beta.belgianbrewed.com/en/product/budweiser-24x30cl](Example page)
The file in question can be found on /assets/angular/controllers/ShopActionController.js
Any thoughts where the problem could be?
The code calls: showPopup(ProductId,'BuyImmediate') in ShopActionController.js
app.controller('ShopActionDialogController', ['$scope', 'CurrentProduct', function ($scope, CurrentProduct) {
$scope.CurrentProduct = CurrentProduct;
console.log("Dialog called and ...");
console.log(CurrentProduct);
//modal.element.modal();
//modal.close.then(function (result) {
// $scope.message = result ? "You said Yes" : "You said No";
//});
}]);
app.controller('ShopActionController', ['$rootScope', '$scope', '$injector', '$http', '$timeout', 'ModalService', 'EndpointService', 'ImageResizeService', 'hotkeys',
function ($rootScope, $scope, $injector, $http, $timeout, ModalService, EndpointService, ImageResizeService, hotkeys) {
$scope.Resize = ImageResizeService;
$scope.Amount;
$scope.InitAmount;
$scope.ProductId;
$scope.ProductVariantId;
$scope.OrderLineId;
$scope.isLoading = false;
$scope.isShown = true;
//$scope.addedToCart = false; //new - not implemented
$scope.inCartAmount = 0; //new - not implemented
$scope.inWishList = false;
$scope.Change = function (Amount) {
$scope.Amount += Amount;
}
$scope.showPopup = function (ProductId,action) {
EndpointService.searchProducts(undefined, 0, 1, ProductId).then(function (response) {
ModalService.showModal({
templateUrl: "ProductPopup.html",
controller: "ShopActionDialogController",
inputs: {
CurrentProduct: response.data[0]
}
}).then(function (modal) {
// The modal object has the element built, if this is a bootstrap modal
// you can call 'modal' to show it, if it's a custom modal just show or hide
// it as you need to.
// console.log("test");
modal.element.modal();
var args = {
Amount: $scope.Amount,
ProductId: response.data[0].Id,
ProductVariantId: response.data[0].ProductVariantId,
OrderLineId: undefined,
InitAmount : $scope.InitAmount
};
if (action != undefined) {
args.Action = action;
}
$rootScope.$broadcast('init', args);
$scope.Amount = $scope.InitAmount;
modal.element.on('hidden.bs.modal', function (e) {
// $scope.Amount = $scope.InitAmount;
console.log("hidden");
modal.element.remove();
// close(result, 200);
});
modal.close.then(function (result) {
// console.log("close");
$scope.Amount = $scope.InitAmount;
modal.element.remove();
// close(result, 200);
//ModalService.closeModals();
// $scope.message = result ? "You said Yes" : "You said No";
});
});
});
}
$scope.CurrentProduct;// = CurrentProduct;
$scope.initiated = false;
var initListener = $scope.$on('init', function (event,args) {
if (!$scope.initiated) {
$scope.Amount = args.Amount;
$scope.InitAmount = args.InitAmount;
$scope.ProductId = args.ProductId;
$scope.ProductVariantId = args.ProductVariantId;
$scope.OrderLineId = args.OrderLineId;
switch (args.Action)
{
case 'BuyImmediate':
$scope.AddToCart();
break;
case 'View':
break;
}
}
});
$scope.$on('$destroy', function () {
console.log("killing this scope");
initListener();
});
$scope.init = function (Amount, ProductId, ProductVariantId, OrderLineId) {
$scope.initiated = true;
$scope.Amount = Amount;
$scope.InitAmount = Amount;
$scope.ProductId = ProductId;
$scope.ProductVariantId = ProductVariantId;
$scope.OrderLineId = OrderLineId;
}
$scope.getSpecification = function (Product,SpecificationId, SpecificationName) {
var Spec = undefined;
angular.forEach(Product.Specifications, function (elem, i) {
if (elem.SpecificationCandidate.SpecificationId == SpecificationId ||
elem.SpecificationCandidate.Specification.Name == SpecificationName) {
Spec = elem.SpecificationCandidate;
}
});
return Spec;
}
$scope.isAddedInCart = function () {
return $scope.OrderLineId != undefined;
}
$scope.PriceInclusive = function (orderline) {
return orderline.Amount * orderline.Product.Price * 1.21;
}
$scope.PriceExclusive = function (orderline) {
return orderline.Amount * orderline.Product.Price;
}
$scope.bindKeys = function () {
hotkeys.add({
combo: '+',
description: 'Add 1 to ammount',
callback: function () {
$scope.Amount += 1;
}
});
hotkeys.add({
combo: '-',
description: 'Substract 1 from ammount',
callback: function () {
if ($scope.Amount > 0) {
$scope.Amount -= 1;
}
}
});
}
$scope.IncrementWith = function (Amount) {
var newAmount = $scope.Amount + Amount;
if (newAmount >= 0) {
$scope.Amount = newAmount;
}
}
$scope.ChangeSortBy = function (SortBy) {
console.log("Changing Sort By");
}
$scope.ChangePageSize = function (PageSize) {
console.log("Changing PageSize");
}
$scope.GetCart = function () {
return EndpointService.orderlines;
}
$scope.RemoveOrderLine = function ($event) {
$scope.isLoading = true;
EndpointService.removeOrderLine($scope.OrderLineId)
.then(function (response) {
EndpointService.orderlines = response.data;
$rootScope.$broadcast('DeleteOrderLine', { OrderLineId: $scope.OrderLineId });
$scope.isLoading = false;
$scope.isShown = false;
});
$event.preventDefault();
return false;
}
$scope.AddToWishlist = function () {
//AddToWishlist
EndpointService.addToWishList($scope.ProductId)
.then(function (response) {
//return true;
$scope.inWishList = true;
});
return false;
}
$scope.RemoveFromWishlist = function () {
EndpointService.removeFromWishList($scope.ProductId)
.then(function (response) {
//return true;
$scope.isShown = false;
});
return false;
}
$scope.PrepareAddOrderLineRequest = function (onlyBulk) {
if (!onlyBulk || (onlyBulk && $scope.InitAmount == 0 && $scope.InitAmount < $scope.Amount)) {
var request = EndpointService.UpdateAmountRequest;
request.OrderLineId = $scope.OrderLineId;
request.Amount = $scope.Amount;
request.ProductId = $scope.ProductId;
return request;
} else {
return undefined;
}
}
$scope.FocusAmountInput = function () {
if ($scope.Amount == $scope.InitAmount) {
$scope.Amount = "";
}
}
$scope.LeaveAmountInput = function () {
if ($scope.Amount == "") {
$scope.Amount = $scope.InitAmount;
}
}
$scope.$on("BroadCastBulkOrders", function () {
var request = $scope.PrepareAddOrderLineRequest(true);
if (request != undefined) {
$rootScope.$broadcast("AddBulkOrder", request);
$scope.Amount = $scope.InitAmount;
}
});
$scope.AddToCart = function () {
$scope.isLoading = true;
var request = $scope.PrepareAddOrderLineRequest(false);
EndpointService.updateAmount(request)
.then(function (response) {
EndpointService.orderlines = response.data;
$rootScope.$broadcast('BasketChanged');
angular.forEach(response.data, function (elem, i) {
if (elem.ProductId == $scope.ProductId) {
$scope.OrderLineId = elem.Id;
$scope.inCartAmount = elem.Amount;
}
});
$scope.Amount = $scope.InitAmount;
$scope.isLoading = false;
});
return false;
}
$scope.UpdateOrderLine = function () {
//$emit required values
$scope.isLoading = true;
var request = $scope.PrepareAddOrderLineRequest(false);
request.isFixed = true;
EndpointService.updateAmount(request)//$scope.OrderLineId, $scope.ProductId, $scope.Amount, true)
.then(function (response) {
angular.forEach(response.data, function (elem, i) {
if (elem.Id == $scope.OrderLineId) {
$rootScope.$broadcast('ChangeAmount', { OrderLineId: $scope.OrderLineId, Amount: $scope.Amount });
}
});
$scope.isLoading = false;
});
return false;
}
}]);
The service
app.service('EndpointService', ['$http', '$q', function ($http, $q) {
this.orderlines = new Array();
//search for products, standard paging included
this.searchProducts = function (searchTerm, page, pageSize, productId) {
var endPoint = "/api/Endpoint/SearchProducts?$expand=Tags,Specifications($expand=SpecificationCandidate($expand=Specification)),CoverPhoto";
if (searchTerm != undefined && searchTerm.length > 0) {
endPoint = endPoint + "&$filter=indexof(Title,'" + searchTerm + "') gt -1"; //make a var
} else if (productId !== undefined) {
{
endPoint = endPoint + "&$filter=Id eq " + productId + " "; //make a var
}
//endPoint = endPoint + "&$filter=";
}
endPoint = endPoint + "&$skip=0&$top=" + pageSize;
return $http.get(endPoint);
//.then(function (response) {
// //console.log(response.data);
// return response.data;
//})
}
// this.ShippingCost = $q.defer();
this.ShippingCost = new Object();
this.calculateShipping = function (address, shippingMethodId) {
if (address == undefined) {
return this.ShippingCost;
} else {
//https://appendto.com/2016/02/working-promises-angularjs-services/
//var deferred = $q.defer();
var endPoint = "/api/Endpoint/CalculateShippingCost?timestamp=" + Date.now();
return $http({
url: endPoint,
method: "GET",
params: {
DeliveryAddress: address,
ShippingMethodId: shippingMethodId,
timestamp: Date.now()
}
})
}
}
this.getOrderLines = function () {
var endPoint = "/api/Endpoint/GetOrder";
return $http({
url: endPoint,
method: "GET",
params: {
timestamp : Date.now()
}
})
.then(function (response) {
this.orderlines = response.data;
return this.orderlines;
});
}
this.removeOrderLine = function (OrderLineId) {
var endPoint = "/api/Endpoint/RemoveOrderLine";
return $http({
url: endPoint,
method: "POST",
params: {
OrderLineId: OrderLineId
}
});
}
this.addToWishList = function (ProductId) {
var endPoint = "/api/Endpoint/AddToWishlist";
return $http({
url: endPoint + "?ProductId=" + ProductId,
method: "GET"
});
}
this.removeFromWishList = function (ProductId) {
var endPoint = "/api/Endpoint/RemoveFromWishlist";
return $http({
url: endPoint + "?ProductId=" + ProductId,
method: "GET"
});
}
this.UpdateAmountRequest = {
ProductId: "",
Amount: 0,
OrderLineId: "",
isFixed : false
}
this.bulkUpdateAmount = function (request) {
var endPoint = "/api/Endpoint/BulkAddOrderLines";
return $http({
url: endPoint,
method: "POST",
headers: {
'Content-Type': "application/json"
},
data: request
});
}
this.updateAmount = function (request){//OrderLineId,ProductId, Amount, isFixed) {
var endPoint = "/api/Endpoint/AddOrderLine?timestamp="+ Date.now();
//console.log("hey, changing the amount " + Amount + " for product id " + ProductId + " are you? :) ");
return $http({
url: endPoint,
method: "POST",
headers: {
'Content-Type': "application/json"
},
data: request
});
}
}]);
You need to add your bootstrap modal hidden listener to the dialog controller context.
app.controller('ShopActionDialogController', ['$scope', '$element', 'CurrentProduct', 'close', function ($scope, $element, CurrentProduct, close) {
$scope.CurrentProduct = CurrentProduct;
console.log("Dialog called and ...");
console.log(CurrentProduct);
//modal.element.modal();
//modal.close.then(function (result) {
// $scope.message = result ? "You said Yes" : "You said No";
//});
//listen for when the modal is dismissed and resolve the ModalService Close promise
$element.on('hidden.bs.modal', function (e) {
close({
currentProduct: CurrentProduct
}, 200); // close, but give 200ms for bootstrap to animate
});
}]);
Note that $element and close were added to the controller dependencies.

Incorrect injection token! Expected service name as string, got function ($scope, AllocateService, testService )

Kindly help me in rectifying the error
myApp.controller('AllocateController', [ '$scope','AllocateService','testService',
function ($scope, AllocateService, testService) {
//code line
},
function ($scope, testService, AllocateService) {
//code line
}]);
The code in detail
myApp.factory('testService', function ($http) {
var fac = {};
fac.GetLastContact = function () {
return $http.get('/Data/PartsAvailable');
}
return fac;
});
myApp.factory('AllocateService', function ($http) {
var fac = {};
fac.SaveFormData = function (data) {
var defer = $q.defer();
$http({
url: '/Data/LeaveReq',
method: 'POST',
data: JSON.stringify(data),
headers: { 'content-type': 'application/json' }
}).success(function (d) {
// Success callback
defer.resolve(d);
}).error(function (e) {
//Failed Callback
alert('Error!');
defer.reject(e);
});
return defer.promise;
}
return fac;
});
myApp.controller('AllocateController', [ '$scope', 'AllocateService','testService',
function ($scope, AllocateService, testService ) {
$scope.Allocate = null;
testService.GetLastContact().then(function (d) {
$scope.Allocate = d.data; // Success
}, function () {
alert('Failed'); // Failed
});
},
function ($scope, testService, AllocateService) {
$scope.submitText = "Save";
$scope.submitted = false;
$scope.message = '';
$scope.isFormValid = false;
$scope.User = {
TaskName: '',
ProductName: ''
};
$scope.$watch('Allocateform.$valid', function (newValue) {
$scope.isFormValid = newValue;
});
//Save Data
$scope.SaveData = function (data) {
if ($scope.submitText == 'Save') {
$scope.submitted = true;
$scope.message = '';
if ($scope.isFormValid) {
$scope.submitText = 'Please Wait...';
$scope.User = data;
testService.SaveFormData($scope.User).then(function (d) {
alert(d);
if (d == 'Success') {
//have to clear form here
ClearForm();
}
$scope.submitText = "Save";
});
}
else {
$scope.message = 'Please fill required fields value';
}
}
}
//Clear Form (reset)
function ClearForm() {
$scope.User = {};
$scope.User.$setPristine(); //here f1 our form name
$scope.submitted = false;
}
}]);
You are defining the controller function twice.
angular.controller() expects an array with strings that reference an injectable entity and the last array member defines the controller function/class.
myApp.controller('AllocateController', [ '$scope', 'AllocateService','testService',
function ($scope, AllocateService, testService ) {
$scope.Allocate = null;
testService.GetLastContact().then(function (d) {
$scope.Allocate = d.data; // Success
}, function () {
alert('Failed'); // Failed
});
$scope.submitText = "Save";
$scope.submitted = false;
$scope.message = '';
$scope.isFormValid = false;
$scope.User = {
TaskName: '',
ProductName: ''
};
$scope.$watch('Allocateform.$valid', function (newValue) {
$scope.isFormValid = newValue;
});
//Save Data
$scope.SaveData = function (data) {
if ($scope.submitText == 'Save') {
$scope.submitted = true;
$scope.message = '';
if ($scope.isFormValid) {
$scope.submitText = 'Please Wait...';
$scope.User = data;
testService.SaveFormData($scope.User).then(function (d) {
alert(d);
if (d == 'Success') {
//have to clear form here
ClearForm();
}
$scope.submitText = "Save";
});
}
else {
$scope.message = 'Please fill required fields value';
}
}
}
//Clear Form (reset)
function ClearForm() {
$scope.User = {};
$scope.User.$setPristine(); //here f1 our form name
$scope.submitted = false;
}
}]);

The correct definition of data

i have this code, when i run it i get an error of "ReferenceError: data is not defined" i have defined data in several ways but nothing seem to be correct. the thing is that when i think about it data is declared in api (no?).. would appreciate some help..
app.service('StatisticsService',
['apiClient', '$q', '$rootScope', '$timeout',
function (apiClient, $q, $rootScope, $timeout) {
var self = this;
self.getStatisticsFromServer = function (data) {
var deferred = $q.defer(); //1
apiClient.getStatsTopMeeters(data)
.then(function (response) { //2
console.log('externalApiConnect', response);
if (response.data.length === 0 || response.result !== "success") {
// TODO: show error
deferred.reject(response);
}
var stats = response.data;
stats = self.getUserProfiles(stats);
deferred.resolve(stats);//3
}
, function (error) {
deferred.reject(error);
console.error(error);
});
return deferred.promise; //4
};
self.getUserProfiles = function (stats) {
var deferred = $q.defer();
var emails = [];
for (var i = 0; i < stats.length; i++) {
emails.push(stats[i].email);
}
console.log(emails);
var data2 = {
token: data.token,
profile_emails: emails
};
apiClient.getUserProfiles(data2).then(function (response2) {
console.log('getUserProfiles', (response2));
if (response2.data.length === 0 || response2.result !== "success") {
// TODO: show error
deferred.reject(response2);
}
var stats = response2.data;
deferred.resolve(stats);//3
}
);
};
}]);
this is some of the apiClient page
app.service('apiClient', ['$http', '$q','$rootScope', function ($http, $q, $rootScope) {
var canceler = $q.defer();
var request = function (apiMethod, apiResponse) {
switch (apiMethod) {
case 'set_meeting_note':
case 'get_meeting_details':
case 'get_account_details':
case 'get_availability':
case 'get_best_time':
case 'get_participants_statuses':
case 'check_user_verified_send_email':
case 'get_participants_statuses':
case 'get_user_profiles':
case 'set_calendar_settings':
case 'sync_external_apis':
$rootScope.showLoader = false;
break;
default:
$rootScope.showLoader = true;
break;
}
var config = {
method: 'POST',
url: apiPath + apiMethod,
data: apiResponse,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
withCredentials: true,
timeout: canceler.promise
};
$http(config).success(function (data) {
$rootScope.showLoader = false;
if (data.message === undefined) {
deferred.resolve(data);
} else {
deferred.reject(data);
}
}).error(function (data, status, headers, config) {
$rootScope.showLoader = false;
deferred.reject(data);
});
return deferred.promise;
};
return {
getStatsTopMeeters: function (data) {
return request('get_stats_top_meeters',data );
},
getUserProfiles: function(data){
return request('get_user_profiles',data);
},
}

Storing tokens with OAuth 2.0 in Angular

I have an app which displays Google Calendar data, but it requires an initial login. I know it's possible to store tokens using OAuth 2.0, but I'm not sure how to go about doing it. Here is my code below. I'd like for the webpage to display the a calendar using JSON data from a google calendar without login.
Controller
angular.module('demo', ["googleApi"])
.config(function(googleLoginProvider) {
googleLoginProvider.configure({
clientId: '239511214798.apps.googleusercontent.com',
scopes: ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/plus.login"]
});
})
.controller('DemoCtrl', ['$scope', 'googleLogin', 'googleCalendar', 'googlePlus', function ($scope, googleLogin, googleCalendar, googlePlus) {
$scope.login = function () {
googleLogin.login();
};
$scope.$on("googlePlus:loaded", function() {
googlePlus.getCurrentUser().then(function(user) {
$scope.currentUser = user;
});
})
$scope.currentUser = googleLogin.currentUser;
$scope.loadEvents = function() {
this.calendarItems = googleCalendar.listEvents({calendarId: this.selectedCalendar.id});
}
$scope.loadCalendars = function() {
$scope.calendars = googleCalendar.listCalendars();
}
}]);
googleAPi
angular.module('googleApi', [])
.value('version', '0.1')
.service("googleApiBuilder", function($q) {
this.loadClientCallbacks = [];
this.build = function(requestBuilder, responseTransformer) {
return function(args) {
var deferred = $q.defer();
var response;
request = requestBuilder(args);
request.execute(function(resp, raw) {
if(resp.error) {
deferred.reject(resp.error);
} else {
response = responseTransformer ? responseTransformer(resp) : resp;
deferred.resolve(response);
}
});
return deferred.promise;
}
};
this.afterClientLoaded = function(callback) {
this.loadClientCallbacks.push(callback);
};
this.runClientLoadedCallbacks = function() {
for(var i=0; i < this.loadClientCallbacks.length; i++) {
this.loadClientCallbacks[i]();
}
};
})
.provider('googleLogin', function() {
this.configure = function(conf) {
this.config = conf;
};
this.$get = function ($q, googleApiBuilder, $rootScope) {
var config = this.config;
var deferred = $q.defer();
return {
login: function () {
gapi.auth.authorize({ client_id: config.clientId, scope: config.scopes, immediate: false}, this.handleAuthResult);
return deferred.promise;
},
handleClientLoad: function () {
gapi.auth.init(function () { });
window.setTimeout(checkAuth, 1);
},
checkAuth: function() {
gapi.auth.authorize({ client_id: config.clientId, scope: config.scopes, immediate: true }, this.handleAuthResult );
},
handleAuthResult: function(authResult) {
if (authResult && !authResult.error) {
var data = {};
$rootScope.$broadcast("google:authenticated", authResult);
googleApiBuilder.runClientLoadedCallbacks();
deferred.resolve(data);
} else {
deferred.reject(authResult.error);
}
},
}
};
})
.service("googleCalendar", function(googleApiBuilder, $rootScope) {
var self = this;
var itemExtractor = function(resp) { return resp.items; };
googleApiBuilder.afterClientLoaded(function() {
gapi.client.load('calendar', 'v3', function() {
self.listEvents = googleApiBuilder.build(gapi.client.calendar.events.list, itemExtractor);
self.listCalendars = googleApiBuilder.build(gapi.client.calendar.calendarList.list, itemExtractor);
self.createEvent = googleApiBuilder.build(gapi.client.calendar.events.insert);
$rootScope.$broadcast("googleCalendar:loaded")
});
});
})
.service("googlePlus", function(googleApiBuilder, $rootScope) {
var self = this;
var itemExtractor = function(resp) { return resp.items; };
googleApiBuilder.afterClientLoaded(function() {
gapi.client.load('plus', 'v1', function() {
self.getPeople = googleApiBuilder.build(gapi.client.plus.people.get);
self.getCurrentUser = function() {
return self.getPeople({userId: "me"});
}
$rootScope.$broadcast("googlePlus:loaded")
});
});
})
What you will want to do is after the result comes back you will want to save it off to localStorage or a cookie and then use that in the future if it exists.
Essentially you will need to update your handleAuthResult to store the result from the Google API:
handleAuthResult: function (authResult) {
if (authResult && !authResult.error) {
var data = {};
$rootScope.$broadcast("google:authenticated", authResult);
googleApiBuilder.runClientLoadedCallbacks();
// here you will store the auth_token
window.localStorage.setItem('auth_token', authResult.token /*I don't know what this response looks like, but it should be similar to this*/ );
deferred.resolve(data);
} else {
deferred.reject(authResult.error);
}
},
Live Demo

Resources