Update in service not reflecting in controller. AngularJS - angularjs

I've ProductService and ProductsController. ProductService have ProductService.Products = []; variable which contains all the Products information.
I access this Products-information in ProductsController and stores in variable named $scope.Products = [];.
Problem is some other service also using "ProductService", and updating "Products Info", using "UpdateInfo" function exposed in ProductService. Now these changes are not getting reflected in ProductsController variable $scope.Products = [];.
This is my code.
sampleApp.factory('ProductService', ['$http', '$q', function ($http, $q){
var req = {
method: 'POST',
url: 'ProductData.txt',
//url: 'http://localhost/cgi-bin/superCategory.pl',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }//,
//data: { action: 'GET' }
};
var ProductService = {};
ProductService.Products = [];
return {
GetProducts: function () {
var defer = $q.defer();
$http(req).then(function(response) {
ProductService.Products = response.data;
defer.resolve(ProductService.Products);
}, function(error) {
defer.reject("Some error");
});
return defer.promise;
},
UpdateInfo: function (ProductID, VariantID) {
for (i in ProductService.Products) {
if (ProductService.Products[i].ProductID == ProductID) {
for (j in ProductService.Products[i].Variants) {
if (ProductService.Products[i].Variants[j].VariantID == VariantID) {
ProductService.Products[i].Variants[j].InCart = 1; /* Updating Info Here, But its not reflecting */
break;
}
}
break;
}
}
}
};
}]);
sampleApp.controller('ProductsController', function ($scope, $routeParams, ProductService, ShoppingCartService) {
$scope.Products = [];
$scope.GetProducts = function() {
ProductService.GetProducts().then
(
function(response) {
$scope.Products = response;
},
function(error) {
alert ('error worng');
}
);
};
$scope.GetProducts();
});
Can some one help me how to solve this issue?

You can create a $watch on ProductService.Products in your controller. When the value changes, you can update $scope.Products with the new value.
$scope.$watch('ProductService.Products', function() {
$scope.Products = ProductService.Products;
});

Try assigning ProductsService.Products to $scope.products.
$scope.GetProducts = function() {
ProductService.GetProducts().then
(
function(response) {
$scope.Products = ProductService.Products;
},
function(error) {
alert ('error worng');
}
);
};

Related

Angular pass parameters and receive json

I am using this service to get json data. How can I pass two parameters as well. With the json I need to populate a drop down.
myApp.service('allCurrentSettingsService', ['$http', '$q', function ($http, $q) {
var allSettings = null;
this.getList = function () {
var def = $q.defer()
if (allSettings) {
def.resolve(allSettings);
} else {
$http.post('GetAllCurrentSettings', { companyName: compName, customerName: custName })
.then(function (response) {
var response = $.parseJSON(response.data)
allSettings = response;
def.resolve(allSettings);
});
}
return def.promise;
}
}]);
And here I am calling the service:
myApp.controller('myController', ['$scope', 'getDocTypesService',
function ($scope, getDocTypesService) {
$scope.getDocTypes = '';
getDocTypesService.getList(compName, custName).then(function (value ) {
$scope.getDocTypes = value
});
}
]);
You missed the function parameters. Please add the same in function definition.
this.getList = function (compName, custName) {
var def = $q.defer()
if (allSettings) {
def.resolve(allSettings);
} else {
$http.post('GetAllCurrentSettings', { companyName: compName, customerName: custName })
.then(function (response) {
var response = $.parseJSON(response.data)
allSettings = response;
def.resolve(allSettings);
});
}
return def.promise;
}
You can call the $http.post() in other ways also:
var data = {param:'val1',.....}
$http({
url: "time.php",
method: "POST",
params: data
})

$scope is not updated after database trigger

I have following controller which is posting a new user and also getting new users.
The problem here is after adding a new user, the scope is not updated so view is not affected. I have also tired returning the function so it expects a promise but didnt update the scope.
myapp.controllers('users', ['usersService', ''$scope',', function(usersService, $scope){
getUsers();
function getUsers(params) {
if (typeof(params) === "undefined") {
params = {page: 1};
}
usersService.getUsers(params).then(function (res) {
$scope.users = res.items;
$scope.usersListTotalItems = res._meta.totalCount;
$scope.usersListCurrentPage = res._meta.currentPage + 1;
});
}
}
$scope.addUser = function (user) {
usersService.adddNewUser(user).then(function (response) {
getUsers();
});
}
}]);
myApp.factory('userService', ['Restangular', '$http', function (Restangular, $http) {
return {
getUsers: function (params) {
var resource = 'users/';
var users = Restangular.all(resource);
return users.getList(params)
.then(function (response) {
return {
items : response.data[0].items,
_meta : response.data[0]._meta
}
});
},
adddNewUser: function (items) {
var resource = Restangular.all('users');
var data_encoded = $.param(items);
return resource.post(data_encoded, {}, {'Content-Type': 'application/x-www-form-urlencoded'}).
then(function (response) {
return response;
},
function (response) {
response.err = true;
return response;
});
}
};
}]);
I think it is a small error however you did not include $scope in the argument for the controller function.
myapp.controllers('users', ['usersService','$scope', function(usersService $scope){
getUsers();
function getUsers(params) {
if (typeof(params) === "undefined") {
params = {page: 1};
}
usersService.getUsers(params).then(function (res) {
$scope.users = res.items;
$scope.usersListTotalItems = res._meta.totalCount;
$scope.usersListCurrentPage = res._meta.currentPage + 1;
});
}
}
$scope.addUser = function (user) {
usersService.adddNewUser(user).then(function (response) {
getUsers();
});
}
}]);

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

Http Promise not resolving in controller

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

Angular controller won't update the view for some reason

I have a service that looks like:
myApp.service('peerService', [
'$http', function($http) {
this.getPeers = function() {
return $http({
url: '/api/v1/peers',
method: 'GET'
});
};
}
]);
In my controller, I have:
myApp.controller('PeerComparisonController', [
'$scope', '$rootScope', 'peerService', function($scope, $rootScope, peerService) {
$scope.init = function() {
$rootScope.pageTitle = 'Peer Comparison';
return $scope.peers = [];
};
$scope.getPeers = function() {
return peerService.getPeers().then(function(response) {
console.log(response);
return $scope.peers = response.data;
});
};
return $scope.init();
}
]);
My view has {{ peers }} in it. This does not get updated when the service returns. I've tried:
peerService.getPeers().then(function(response) {
return $scope.$apply(function() {
return $scope.peers = response.data;
});
});
And that also doesn't work. So any ideas?
you try something like this
myApp.service('peerService', [
'$http', function($http) {
this.getPeers = function() {
return $http({method: 'GET', url:'/api/v1/peers'}).
then(function(response) {
return response.data;
});
};
}
]);
or
myApp.service('peerService', ['$http', function ($http) {
this.getPeers = function () {
var deferred = $q.defer();
$http({ method: 'GET', url: '/api/v1/peers' }).
then(function (response) {
deferred.resolve(response.data);
});
return deferred.promise;
};
}
]);

Resources