Login with Google using AngularJS - angularjs

$scope.authenticateGoogle = function(google) {
var params = {
'clientid':'something',
'cookiepolicy':'single_host_origin',
'callback': function(result){
if(result['status']['signed_in']){
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp){
$scope.$apply(function(){
//
});
});
});
}
},
'approvalprompt':'force',
'scope':'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read'
};
gapi.auth.signIn(params);
};
Users land on the permissions screen upon every login.
How can I fix this code?
Google says that for basic information it does not require approval.
Please guide me.
Thanks a ton in advance

You're good try remove 'approvalprompt':'force',
$scope.authenticateGoogle = function(google) {
var params = {
'clientid':'something',
'cookiepolicy':'single_host_origin',
'callback': function(result){
if(result['status']['signed_in']){
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp){
$scope.$apply(function(){
//
});
});
});
}
},
'scope':'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read'
};
gapi.auth.signIn(params);
};

Related

Second jsonp http get request - using $q gives 404 error despite GET showing 200

I've found a couple of similar posts to this, but the answers (which boil down to putting callback=JSONP_CALLBACK into the get request) aren't working for me. Using that in the request generates an immediate 404 error, while using callback=angular.callbacks._0 at least lets the first request return a successful response. The problem is that using the very same request function with the very same params a second time to refresh the data or get the next 20 objects, returns a 404 error even though the actual get returns a 200 and the data can be seen in chrome tools.
I'm, new to using $q deferred promises, so I'm hoping that the issue has something to do with that not allowing enough time for a response before executing the reject. I'm attaching the code, which involves the Yelp API as did the other couple of posts I found on this issue. The most closely related is: (Subsequent JSONP requests give status 404 despite GET status 200), but there's another which uses the same callback string I'm using (Yelp API and AngularJS).
This particular project is for an ionic mobile app that gets coffee shops based on users geolocation.
Here's the code for the service (secret stuff removed):
var app = angular.module('caffeine.services', []);
app.service("YelpService", function ($q, $http, $cordovaGeolocation, $ionicPopup) {
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
};
var method = 'GET';
var url = 'http://api.yelp.com/v2/search';
var consumerSecret = ''; //Consumer Secret
var tokenSecret = ''; //Token Secret
var self = {
'page': 1,
'isLoading': false,
'hasMore': true,
'results': [],
'ranStr': randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
'timeStamp':new Date().getTime(),
'lat': 51.544440,
'lon': -0.022974,
'term': 'coffee',
'oauthConKey': '', //Consumer Key
'oauthToken': '', //Token
'oauthSigMeth': 'HMAC-SHA1',
'refresh': function () {
self.page = 1;
self.isLoading = false;
self.hasMore = true;
self.results = [];
return self.load();
},
'next': function () {
self.page += 1;
return self.load();
},
'load': function () {
self.isLoading = true;
var deferred = $q.defer();
ionic.Platform.ready(function() {
$cordovaGeolocation
.getCurrentPosition({timeout:10000, enableHighAccuracy:false})
.then(function(position){
self.lat = position.coords.latitude;
self.lon = position.coords.longitude;
console.log('latlong = '+self.lat+','+self.lon);
var params = {
callback: 'angular.callbacks._0',
page: self.page,
ll: self.lat+','+self.lon,
term: self.term,
oauth_consumer_key: self.oauthConKey, //Consumer Key
oauth_token: self.oauthToken, //Token
oauth_signature_method: self.oauthSigMeth,
oauth_timestamp: self.timeStamp,
//new Date().getTime(),
oauth_nonce: self.ranStr
};
var signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, { encodeSignature: false});
params['oauth_signature'] = signature;
console.log('url ='+url);
console.log('params.ll = '+params.ll);
$http.jsonp(url, {params: params}).success(function (callback) {
self.isLoading = false;
console.log(callback.businesses);
if (callback.businesses.length == 0) {
self.hasMore = false;
} else {
angular.forEach(callback.businesses, function (business) {
self.results.push(business);
});
}
self.isLoading = false;
deferred.resolve(callback.businesses);
})
.error( function (callback, status, headers, config) {
self.isLoading = false;
console.error('data not received');
console.error('data: '+callback);
console.error('status: '+status);
console.error('headers: '+headers);
console.error('congig: '+config);
deferred.reject(callback);
});
}, function(err) {
console.error('Error getting position');
console.error(err);
$ionicPopup.alert({
'title': 'Please turn on geolocation',
'template': 'It looks like you have geolocation turned off. Please turn on geolocation in your app settings to use this app.'
});
})
});
return deferred.promise;
}
};
self.load();
return self;
});

Restangular no BaseUrl when do PUT

i'm using Restangular and trying to PUT some data but it seems to lose the BaseUrl.
In the config function i define the BaseUrl for Restangular and others Restangular fields.
Constants.restangularBaseUrl is http://192.168.1.100/api/
RestangularProvider.setBaseUrl(Constants.restangularBaseUrl)
.setRestangularFields({
selfLink: '_links.self.href',
id: '_id',
etag: '_etag'
})
.addResponseInterceptor(function(data, operation, what, url, response, deferred){
if (operation === 'getList') {
var result = data._items;
result._meta = data._meta;
result._links = data._links;
return result;
}
return data;
});
Then i have some models like this:
(function(){
angular.module('models.ebayItems', ['services.constants', 'restangular'])
.service('EbayItems', ['Constants', 'Restangular', function (Constants, Restangular) {
Restangular.extendModel('ebayitems', function(model) {
model.toggleMonitor = function(){
var item = this;
Restangular.one('ebayitems', this._id).patch({active: this.active}, '', {'If-Match': this._etag})
.then(function(data){
item._etag = data._etag;
}, function(error){
console.log('error', error);
});
};
return model;
});
var ebayItems = Restangular.all('ebayitems');
var ebayItemsOneSearch = function(_id){
return ebayItems.customGETLIST('', {where: {searchId: _id}});
};
return {
items: ebayItems,
oneSearch: ebayItemsOneSearch
};
}])
})();
Now when i try to do a put request with an item based on that model:
item.put()
it uses the wrong url, i mean it loses the BaseUrl, so instead of putting at:
http://192.168.1.100/api/ebayitems/12345
it puts at
http://192.168.1.100/ebayitems/12345
resulting in a 404 error.
Why?
What am i doing wrong?
Any help really appreciated.
Thank you
The problem was that setting a selfLink field that was a relative url from the API backend it overrides the BaseUrl.
Removing that field from the config function it worked.
RestangularProvider.setBaseUrl(Constants.restangularBaseUrl)
.setRestangularFields({
id: '_id',
etag: '_etag'
})
.addResponseInterceptor(function(data, operation, what, url, response, deferred){
if (operation === 'getList') {
var result = data._items;
result._meta = data._meta;
result._links = data._links;
return result;
}
return data;
});

is invoking a service into another service in angular

I need to save data and then I need to dispaly the changes immediately afterwards.
That's why I Have a
updateSaisine which allows me to update data
getOneSaisine which allows me get the data and display them:
Which is the more correct way and for which reasons ?
Should I write:
$scope.saveSaisine = function() {
saisineSrv.updateSaisine($scope.currentSaisine.idSaisine, $scope.currentSaisine).
then(
function() {
$scope.errorMessages = [];
if ($scope.currentSaisine.idMotif) {
toaster.pop('success', 'Réponse', 'Success');
angular.element('#modalSaisine').modal('hide');
saisineSrv.getOneSaisine($scope.currentSaisine.idSaisine, $scope.currentSaisine).then(function(response) {
$scope.currentSaisine.dateModif = response.dateModif;
});
},
function error(response) {
$scope.errorMessages = response.data;
toaster.pop('error', 'Réponse', 'We have a problem');
}
);
};
OR
$scope.saveSaisine = function() {
saisineSrv.updateSaisine($scope.currentSaisine.idSaisine, $scope.currentSaisine).
then(
function() {
$scope.errorMessages = [];
if ($scope.currentSaisine.idMotif) {
toaster.pop('success', 'Réponse', 'Success');
angular.element('#modalSaisine').modal('hide');
},
function error(response) {
$scope.errorMessages = response.data;
toaster.pop('error', 'Réponse', 'We have a problem');
}
);
saisineSrv.getOneSaisine($scope.currentSaisine.idSaisine, $scope.currentSaisine).then(function(response) {
$scope.currentSaisine.dateModif = response.dateModif;
});
};
the first option is a correct way how you should refresh your data because these services are asynchronous thus in the second example you may don't get fresh data (the getOneSaisine can finish before updateSaisine).

Uploading images to Firebase with AngularJS

I have a service that handles "episodes": creating, deleting and updating them. It looks like this:
app.service('Episode', ['$firebase', 'FIREBASE_URL', function($firebase, FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL);
var episodes = $firebase(ref);
return {
all: episodes,
create: function(episode) {
location.reload();
//Add to firebase db
return episodes.$add(episode);
},
delete: function(episodeId) {
location.reload();
return episodes.$remove(episodeId);
},
update: function(episode) {
location.reload();
return episodes.$save(episode);
}
};
}]);
Inside my controller:
app.controller('AdminCtrl', ['$scope', 'Episode', function ($scope, Episode) {
$scope.episodes = Episode.all;
$scope.createEpisode = function(){
Episode.create($scope.episode).then(function(data){
$scope.episode.name = '';
$scope.episode.title = '';
$scope.episode.description = '';
$scope.episode.time = '';
$scope.episode.img = '';
});
};
$scope.deleteEpisode = function(episodeId){
if(confirm('Are you sure you want to delete this episode?') === true) {
Episode.delete(episodeId).then(function(data){
console.log('Episode successfully deleted!');
});
}
};
$scope.updateEpisode = function(episode) {
Episode.update($scope.episode).then(function(data) {
console.log('Episode successfully updated.');
});
};
The only example of uploading images to Firebase from AngularJS I've seen online is this: https://github.com/firebase/firepano
How am I able to incorporate this into an object based addition/update instead of finding it's index/link?

Event loop Angular. Some functions not running on app initialisation until a button is clicked? -FIREBASE

Background:
I have the following setup to authenticate retrieve my user and then retrieve his credentials. I am unclear on the event loop even after reading the documentation.
The Question:
The user is not displayed until I click a button? Every other kind of function runs on initialization like the alerts and stuff but why is my retrieve user function working until another button is pressed (pressing any button )?
Summary:
In order to retrieve the username for some reason I need to click something. I want the username to be retrieve on initialization .
crossfitApp.controller('globalIdCtrl', ["$scope",'$q','defautProfileData','$timeout', function ($scope,$q,defautProfileData,$timeout) {
$timeout(function() {
var dataRef = new Firebase("https://glowing-fire-5401.firebaseIO.com");
$scope.myFbvar =null;
$scope.authenticated={
currentUser: null,
avatarUrl: "",
emailAddress: "",
settings: "",
currentUserid: null,
};
function getProfile(userID){
myprofile= new Firebase("https://glowing-fire-5401.firebaseio.com/profiles/"+userID+"/username");
myprofile.once('value', function(nameSnapshot) {
$scope.authenticated.currentUser = nameSnapshot.val();
});
};
$scope.auth = new FirebaseSimpleLogin(dataRef, function(error, user) {
if (error) {
//Error
console.log ('error');
}
else if (user) {
//logged in
$scope.$apply(function(){getProfile(user.id);})
console.log('logged in');
$scope.authenticated.currentUserid = user.id ;//
}
else {
// user is logged out
console.log('logged out');
$scope.authenticated.currentUserid =null;
$scope.authenticated.currentUserid =null;
}
});
},100);
}]); //GlobaldCtrl
I would move most of your code to a service, and call the service from your controller, like this. I also included a deferred object in your login as I bet this is async
crossfittpApp.service('firebase',function($q) {
return {
getUser : function(authenticated) {
var dataRef = new Firebase("https://glowing-fire-5401.firebaseIO.com"),
myFbvar =null,
getProfile(userID) {
myprofile= new Firebase("https://glowing-fire-5401.firebaseio.com/profiles/"+userID+"/username");
myprofile.once('value', function(nameSnapshot) {
authenticated.currentUser = nameSnapshot.val();
});
},
deferredObj = $q.defer();
auth;
auth = new FirebaseSimpleLogin(dataRef, function(error, user) {
if (error) {
//Error
console.log ('error');
deferObj.reject();
}
else if (user) {
//logged in
getProfile(user.id);
console.log('logged in');
authenticated.currentUserid = user.id ;
deferObj.resolve(auth);
}
else {
// user is logged out
console.log('logged out');
authenticated.currentUserid =null;
deferObj.resolve();
}
}
return deferObj.promise;
}
}
});
crossfittpApp.controller('globalIdCtrl',function(firebase) {
$scope.authenticated = {
currentUser: null,
avatarUrl: "",
emailAddress: "",
settings: "",
currentUserid: null,
};
firebase.getUser(authenticated)
.then(function(_auth) {
$scope.auth = _auth;
},
function() {
//auth error here
});
});
You're not triggering Angular's HTML Compiler, so Angular doesn't know you've changed the JS variables.
Whenever you use an event like ng-click/ng-submit/etc, Angular fires $scope.$apply(), which checks for any changes to your $scope variables and applies them to the DOM, which is why it shows up after this.
You can correct this issue by alerting Angular that it needs to run $apply by using $timeout:
angular.controller('MyController', function($timeout) {
myprofile= new Firebase("https://glowing-fire-5401.firebaseio.com/profiles/"+userID+"/username");
myprofile.once('value', function(nameSnapshot) {
$timeout(function() {
authenticated.currentUser = nameSnapshot.val();
});
});
auth = new FirebaseSimpleLogin(dataRef, function(error, user) {
if (error) {
//Error
console.log ('error');
}
else if (user) {
$timeout(function() {
authenticated.currentUserid = user.id ;
});
}
else {
$timeout(function(){
authenticated.currentUserid =null;
});
}
});
});
You should utilize angularFire, which abstracts these complexities.
There are some more questions like this one here, here, and here.

Resources