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
Related
I'm having some troubles with the local storage and my Ionic app. The thing is quite straight forward - I would like to store to device all the data from from sql database and then display it when the device is without network.
So the code where I get my data from looks like this:
controllers.js:
$http.get('http://someurl.php?type=json')
.success(function(data) {
$scope.info = data;
})
.error(function(response) {
$scope.info = "Error";
});
So can anyone help me out with this one?
Thank you!
I can suggest to you to use some plugin for DB but with localstorage you have to pass (and install) this:
angular-local-storage
and then use it in your JS like:
$http.get('http://someurl.php?type=json')
.success(function(data) {
//test if is online or offline and the do something
if($rootScope.isOnLine)
localStorageService.set("nameofkey", { data:data }); //here you store in your localstorage ... remeber to inject it as dependency
$scope.info = data;
})
.error(function(response) {
$scope.info = "Error";
});
then if you want to know if your ionic app is online or offline you can use this plugin: http://ngcordova.com/docs/plugins/network/
"use strict";
// Ionic Starter App
angular.module("myapp", ["ionic",
"ionic.service.core",
"ngCordova",
"ionic.service.push",
"ngResource",
"LocalStorageModule",
"ionic-native-transitions",
"angularMoment"])
.run(["$ionicPlatform", "authService", "$rootScope", "$timeout", "$cordovaSpinnerDialog", "$window", "$cordovaNetwork", "$state", "ScanService", "$cordovaToast", "localStorageService", "DB",
function ($ionicPlatform, authService, $rootScope, $timeout, $cordovaSpinnerDialog, $window, $cordovaNetwork, $state, ScanService, $cordovaToast, localStorageService, DB) {
$ionicPlatform.ready(function () {
$rootScope.isOnLine = true;
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (ionic.Platform.isIPad() &&
window.cordova &&
window.cordova.plugins &&
window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
// CONNECTION STATE /////////////////////////////////////////////
if ($cordovaNetwork) {
//listen for OnLine event
$rootScope.$on('$cordovaNetwork:online', function (event, networkState) {
var onlineState = networkState;
$rootScope.isOnLine = true;
});
// listen for Offline event
$rootScope.$on('$cordovaNetwork:offline', function (event, networkState) {
var offlineState = networkState;
$rootScope.isOnLine = false;
});
}
//////////////////////////////////////////////////////////////////
});
}]);
This is an exmaple for a Service using it for call http or from local if there is no connection:
"use strict";
angular
.module('gestione')
.factory("ScanService", ["$q", "$resource", "enviroment", "$rootScope", "localStorageService", "DB",
function ($q, $resource, enviroment, $rootScope, localStorageService, DB) {
var self = this;
// Private Fileds
var _serviceBase = "api/Scan/";
var _serviceBaseBarScan = "api/BarScan/";
var _serviceBaseCount = "api/Scan/Count";
var _serviceBaseLast = "api/Scan/Last";
var _serviceBaseAll = "api/Scan/All";
// Private Method
var _resource = $resource(enviroment.apiUrl + _serviceBase, { skip: '#skip', take: '#take' }, {
query: { method: "GET", isArray: true },
create: { method: "POST", isArray: false }
});
var _resourceLast = $resource(enviroment.apiUrl + _serviceBaseLast, {}, {
query: { method: "GET", isArray: false }
});
var _resourceAll = $resource(enviroment.apiUrl + _serviceBaseAll, {}, {
create: { method: "POST", isArray: true }
});
var _resourceCount = $resource(enviroment.apiUrl + _serviceBaseCount, {}, {
query: { method: "GET", isArray: false }
});
var _resourceBar = $resource(enviroment.apiUrl + _serviceBaseBarScan, {}, {
query: { method: "GET", isArray: true },
create: { method: "POST", isArray: false }
});
return {
Get: function (skip, take) {
var deferred = $q.defer();
// IS ONLINE
if ($rootScope.isOnLine) {
_resource.query({ skip, take }).$promise.then(function (resp) {
deferred.resolve(resp);
}).catch(function (err) {
deferred.reject(err);
});
} else { // OffLine
DB.Query("SELECT * FROM Scan ORDER BY ROWID DESC ;").then(function (result) {
var scan = DB.fetchAll(result);
deferred.resolve(scan);
}, function (err) {
deferred.reject(err);
});
}
return deferred.promise;
},
GetLast: function () {
var deferred = $q.defer();
// IS ONLINE
if ($rootScope.isOnLine) {
_resourceLast.query().$promise.then(function (resp) {
deferred.resolve(resp);
}).catch(function (err) {
deferred.reject(err);
});
} else { // OffLine
DB.Query("SELECT * FROM Scan ORDER BY ROWID DESC LIMIT 1 ;").then(function (result) {
var scan = DB.fetch(result);
deferred.resolve(scan);
}, function (err) {
deferred.reject(err);
});
}
return deferred.promise;
},
GetNotSync: function () {
return DB.Query("SELECT * FROM Scan WHERE sync = ? ", ['false']).then(function (result) {
return DB.fetchAll(result);
});
},
CheckInOrOut: function (item) {
return DB.Query("SELECT * FROM Scan WHERE idTicket = ? ORDER BY ROWID DESC LIMIT 1;", [item.IdTicket]).then(function (result) {
return DB.fetch(result);
});
},
Count: function () {
var deferred = $q.defer();
// IS ONLINE
if ($rootScope.isOnLine) {
_resourceCount.query().$promise.then(function (resp) {
deferred.resolve(resp);
}).catch(function (err) {
deferred.reject(err);
});
} else { // OffLine
DB.Query("SELECT COUNT(*) FROM Scan;").then(function (result) {
var scan = DB.fetch(result);
deferred.resolve(scan);
}, function (err) {
deferred.reject(err);
});
}
return deferred.promise;
},
Save: function (scan) {
var deferred = $q.defer();
//We're OnLine
if ($rootScope.isOnLine) {
_resource.create(scan).$promise.then(function () {
scan.sync = true;
}).catch(function () {
scan.sync = false;
}).finally(function () {
DB.Insert(scan).then(function (record) {
deferred.resolve(record);
}).catch(function () {
deferred.reject();
});
});
} else { // OffLine
scan.sync = false;
DB.Insert(scan).then(function (record) {
deferred.resolve(record);
}).catch(function () {
deferred.reject();
});
}
return deferred.promise;
},
Sync: function () {
var self = this;
var deferred = $q.defer();
var allPromise = [];
//get all stored scans
self.GetNotSync().then(function (scanList) {
// send them to the server
if (scanList && scanList.length > 0)
_resourceAll.create(scanList).$promise.then(function (resp) {
//cicle on each record returned from server
resp.forEach(function (item) {
if (item) {
//prepare query
var update_query = "UPDATE Scan SET sync= 'true' WHERE idTicket= " + item.idTicket;
//set sync to true on records
allPromise.push(DB.Update(update_query));
}
});
}).catch(function (err) {
allPromise.push(deferred.reject(err));
});
}).catch(function (error) { allPromise.push(deferred.reject(error)); });
return $q.all(allPromise);
},
GetBarScan: function () {
return _resourceBar.query();
},
SaveBarScan: function (barscan) {
var deferred = $q.defer();
_resourceBar.create(barscan).$promise.then(function (record) {
deferred.resolve(record);
}).catch(function () {
deferred.reject();
});
return deferred.promise;
}
};
}
]);
Is there anyway to call another service form current service ?
/FACTORIES/
app.service('p3call',function($http,$rootScope){
return {
getRepairCategory:function(url){
$http.post(url)
.success(function (response){
generatePaginationData(response);
});
},
deleteRepairCategory:function(request,url){
$http.post(url,request)
.success(function (response){
generatePaginationData(response)
});
},
generatePaginationData:function(response){
var pages = [];
$rootScope.categories = response.data;
$rootScope.currentPage = response.current_page;
$rootScope.totalPages = response.last_page;
for(var i=1;i<=response.last_page;i++) {
pages.push(i);
}
$rootScope.range = pages;
}
};
});
/FACTORIES/
yes it's totally possible:
app.service('p3call',function($http,$rootScope, myOtherService){
return {
getRepairCategory:function(url){
...
},
deleteRepairCategory:function(request,url){
...
},
generatePaginationData:function(response){
...
}
myFunction(){
myOtherService.newFunction();
}
};
});
Just inject your service and use it.
Try using the this reference of the service
app.service('p3call',function($http,$rootScope){
var this = this;
return {
getRepairCategory:function(url){
$http.post(url)
.success(function (response){
this.generatePaginationData(response);
});
},
deleteRepairCategory:function(request,url){
$http.post(url,request)
.success(function (response){
this.generatePaginationData(response)
});
},
generatePaginationData:function(response){
var pages = [];
$rootScope.categories = response.data;
$rootScope.currentPage = response.current_page;
$rootScope.totalPages = response.last_page;
for(var i=1;i<=response.last_page;i++) {
pages.push(i);
}
$rootScope.range = pages;
}
};
});
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');
}
);
};
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();
});
}
}]);
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);
});
}
};