I'm trying to make angular directive button to follow and unfollow leagues ID
every request $http.put going fine but there is a problem with .then method console show me error and the method rejected
here the code
app.factory('FollowedLeagues', ['appConfig', '$http', '$q', function(appConfig, $http, $q){
var FollowedLeagues = {};
FollowedLeagues.follow = function (token, leagueID) {
$http.put(appConfig.apiUrl + 'user/follow-league?token=' + token +'&league_id='+ leagueID +'&status=true' )
.then(function(response){
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
},
function(response) {
// something went wrong
return $q.reject(response.data);
});
};
FollowedLeagues.unfollow = function (token, leagueID) {
$http.put(appConfig.apiUrl + 'user/follow-league?token=' + token +'&league_id='+ leagueID +'&status=false' )
.then(function(response){
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
},
function(response) {
// something went wrong
return $q.reject(response.data);
});
};
return FollowedLeagues;
}]);
app.directive('fbFollowBtn', ['$rootScope', '$compile', 'FollowedLeagues', function ($rootScope, $compile, FollowedLeagues) {
var getLeagueID = function(leagueID, followed){
for(var i=0; i< followed.length; i++) {
var fLeagues = followed[i]._id;
if (fLeagues == leagueID) {
return fLeagues;
}
}
};//End-function.
return {
restrict: 'A',
link:function(scope, element, attrs){
scope.followed = $rootScope.meData.followedLeagues;
scope.leagueid = attrs.leagueid;
var follow_btn = null;
var unfollow_btn = null;
var createFollowBtn = function () {
follow_btn = angular.element('Follow');
$compile(follow_btn)(scope);
element.append(follow_btn);
follow_btn.bind('click', function(e){
scope.submitting = true;
FollowedLeagues.follow($rootScope.userToKen, scope.leagueid)
.then(function(data){
scope.submitting = false;
follow_btn.remove();
createUnfollowBtn();
console.log('followed Leagues Done :-) ', data);
});
// scope.$apply();
});
};
var createUnfollowBtn = function () {
unfollow_btn = angular.element('Unfollow');
$compile(unfollow_btn)(scope);
element.append(unfollow_btn);
unfollow_btn.bind('click', function (e) {
scope.submitting = true;
FollowedLeagues.unfollow($rootScope.userToKen, scope.leagueid)
.then(function(data){
scope.submitting = false;
unfollow_btn.remove();
createFollowBtn();
console.log('followed Leagues Done :-) ', data);
});
// scope.$apply();
});
};
scope.$watch('leagueid', function (val) {
var leag = getLeagueID(scope.leagueid, scope.followed);
if(typeof(leag) == 'undefined'){
createFollowBtn();
} else if(typeof(leag) !== 'undefined'){
createUnfollowBtn();
}//end if
}, true);
}
};
}]);
You have to return your $http.put function inside your service functions. For example the Followedleagues.follow function:
FollowedLeagues.follow = function (token, leagueID) {
return $http.put(appConfig.apiUrl + 'user/follow-league?token=' + token +'&league_id='+ leagueID +'&status=true' )
.then(function(response){
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
},
function(response) {
// something went wrong
return $q.reject(response.data);
});
};
Related
I have a function that needs to return a list of favorite locations. Something like this
LocationsFactory.getFavoriteLocations().then(function($favoriteLocations) {
});
The getFavoriteLocations looks something like this
getFavoriteLocations: function() {
if (favorite_locations.length == 0)
{
var deff = $q.defer();
obj.getDeviceId().then(function(device_id) {
$http.get('url?token=' + device_id).then(function(response) {
favorite_locations = response.data;
deff.resolve(favorite_locations);
return deff.promise;
})
})
} else {
return favorite_locations;
}
}
The getDeviceId again, it's a function based on promise.
getDeviceId: function() {
var deff = $q.defer();
deff.resolve(Keychain.getKey());
return deff.promise;
}
The error that I got is TypeError: Cannot read property 'then' of undefined. Please help!
You can chain promises:
getFavoriteLocations: function () {
if (favorite_locations.length === 0) {
return obj.getDeviceId().then(function (device_id) {
return $http.get('url?token=' + device_id).then(function (response) {
favorite_locations = response.data;
return favorite_locations;
});
});
}
return $q.resolve(favorite_locations);
}
And improve this:
getDeviceId: function() {
return $q.resolve(Keychain.getKey());
}
$q in not necessary here:
if (favorite_locations.length == 0)
{
return obj.getDeviceId() // you have to return a promise here
.then(function(device_id) {
return $http.get('url?token=' + device_id) // you will access the response below
})
.then(function(response) {
favorite_locations = response.data;
return favorite_locations
});
})
}
Now it should work.
Good evening everybody. I startet creating a mobile application with AngularJS,Ionic & Cordova some weeks ago. I try to create a AuthenticationService for this app using a given API.
I checked some tutorials and created this and it seems to work besides the promise handling. I have got a deficit there.
Maybe someone good help me :)
Here i handle the access to certain pages/states.
$rootScope.$on('$stateChangeStart', function (event, next, nextParams, fromState) {
if ('data' in next && 'authorizedRoles' in next.data) {
var authorizedRoles = next.data.authorizedRoles;
if (!AuthService.isAuthorized(authorizedRoles)) {
event.preventDefault();
$state.go($state.current, {}, {
reload: true
});
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
}
}
if (next.name == 'app.admin' || next.name == 'app.bonus') {
AuthService.isAuthenticated().then(function (response) {
}, function (response) {
var alertPopup = $ionicPopup.alert({
title: 'Error1!',
template: 'Sorry, You have to login again.'
});
event.preventDefault();
$state.go('app.login');
$log.log(response + '1er');
});
}
});
Here I perform the user-login
.controller('LoginCtrl', function ($scope, $ionicPopup, AuthService, $state, $log, $q) {
$scope.data = {};
$scope.login = function (data) {
$q.all([
AuthService.login(data.username, data.password),
AuthService.isAuthenticated()
]).then(function (data) {
console.log(data[0]);
console.log(data[1]);
if (data[0] == false) {
var alertPopup = $ionicPopup.alert({
title: 'Error!',
template: 'Sorry, You have to login again.'
});
}
if (data[1] == true) {
$state.go('app.bonus', {}, {
reload: true
});
} else {
var alertPopup = $ionicPopup.alert({
title: 'Error!',
template: 'Sorry, You have to login again.'
});
}
});
};
})
Here I created the service handling the user-role, validation & creation of the cookie - Every API-call needs a nonce which is created also
.service('AuthService', function ($q, $http, USER_ROLES, $log) {
var link = 'http://example/api/';
var username = '';
var isAuthenticated = false;
var role = '';
var mycookie = '';
var mynonce = '';
function checkCookie() {
mycookie = window.localStorage.getItem('LOCAL_COOKIE');
$log.info(mycookie);
if (mycookie) {
$http.get(link + 'get_nonce/?controller=user&method=generate_auth_cookie&insecure=cool').then(
function (result) {
if (result.data.status == "ok") {
mynonce = result.data.nonce;
$log.info(mynonce);
} else {
return false;
}
},
function (err) {
return false;
});
$http.get(link + 'user/validate_auth_cookie/?cookie=' + mycookie + '&nonce=' + mynonce + '&insecure=cool').then(
function (result) {
if (result.data.status == "ok") {
return true;
} else {
window.localStorage.removeItem('LOCAL_COOKIE');
return false;
}
},
function (err) {
return false;
});
} else {
return false;
}
}
function doLogin(name, pw) {
var loginAttempt = false;
$http.get(link + 'get_nonce/?controller=user&method=generate_auth_cookie&insecure=cool').then(
function (result) {
if (result.data.status == "ok") {
mynonce = result.data.nonce;
$log.info(mynonce);
} else {
loginAttempt = false;
}
},
function (err) {
loginAttempt = false;
$log.info(err);
});
mycookie = $http.get(link + 'user/generate_auth_cookie/?username=' + encodeURIComponent(name) + '&password=' + encodeURIComponent(pw) + '&nonce=' + mynonce + '&insecure=cool').then(
function (result) {
if (result.data.status == "ok") {
mycookie = result.data.cookie;
loginAttempt = true;
username = name;
if (username == 'MarkusK') {
role = USER_ROLES.admin
} else {
role = USER_ROLES.public
}
window.localStorage.setItem('LOCAL_COOKIE', mycookie);
$log.info(mycookie);
} else {
loginAttempt = false;
}
},
function (err) {
loginAttempt = false;
$log.info(err);
});
$log.info('test1' + loginAttempt);
return loginAttempt;
};
var login = function (name, pw) {
return $q(function (resolve, reject) {
if (doLogin(name, pw)) {
resolve('Login success.');
} else {
reject('Login Failed.');
}
});
};
var validCookie = function () {
return $q(function (resolve, reject) {
if (checkCookie()) {
resolve('Cookie success.');
} else {
reject('Cookie Failed.');
}
});
};
var logout = function () {
mycookie = undefined;
username = '';
isAuthenticated = false;
window.localStorage.removeItem('LOCAL_COOKIE');
};
var isAuthorized = function (authorizedRoles) {
if (!angular.isArray(authorizedRoles)) {
authorizedRoles = [authorizedRoles];
}
return (checkCookie() && authorizedRoles.indexOf(role) !== -1);
};
return {
login: login,
logout: logout,
isAuthorized: isAuthorized,
isAuthenticated: validCookie,
username: function () {
return username;
},
role: function () {
return role;
}
};
})
Maybe someone got time to help me and I finally understand the promise API.
Thank you.
You have a nice illustrated definition here:
http://andyshora.com/promises-angularjs-explained-as-cartoon.html.
Let' say we have the following code (isn't meaning anything it's only to explain the promise concept):
var a = 1;
a = foo();
a = a + 2;
Because JavaScript is asynchronous, the second instruction (the call to foo()), won't block the thread.
if foo() is waiting for other ressource (value from a server), it won't wait and will get into the third instruction (a = 2).
The promise is used to tell JavaScript thread: "Hey don't forget to comeback when I'll be ready, you promised me :)".
I am using the Angular spyboost utility wrapper. I am trying to reformat it for this angular 1 style guide. I'm having a hard time with parts of it. I think I have most of it correct but the angular.forEach function is throwing me off. I am and am getting an error `Expected '{' and instead saw 'result'. Could someone help me please ?
angular
.module('myMod')
.factory('MyService');
MyService.$inject = ['$rootScope', 'atmosphereService', 'atmosphere'];
function MyService ($rootScope, atmosphere) {
return {
subscribe: subscribe,
getMessage: getMessage
};
function subscribe (r) {
var responseParameterDelegateFunctions = ['onOpen', 'onClientTimeout', 'onReopen', 'onMessage', 'onClose', 'onError'];
var delegateFunctions = responseParameterDelegateFunctions;
var result = {};
delegateFunctions.push('onTransportFailure');
delegateFunctions.push('onReconnect');
angular.forEach(r, function (value, property) {
if (typeof value === 'function' && delegateFunctions.indexOf(property) >= 0) {
if (responseParameterDelegateFunctions.indexOf(property) >= 0)
**result[property] = function (response) {**
$rootScope.$apply(function () {
r[property](response);
});
};
else if (property === 'onTransportFailure')
result.onTransportFailure = function (errorMsg, request) {
$rootScope.$apply(function () {
r.onTransportFailure(errorMsg, request);
});
};
else if (property === 'onReconnect')
result.onReconnect = function (request, response) {
$rootScope.$apply(function () {
r.onReconnect(request, response);
});
};
} else
result[property] = r[property];
});
function getMessage () {
var vm = this;
var request = {
url: '/chat',
contentType: 'application/json',
transport: 'websocket',
reconnectInterval: 5000,
enableXDR: true,
timeout: 60000
};
request.onMessage(response); {
vm.$apply (function () {
vm.model.message = atmosphere.util.parseJSON(response.responseBody);
});
}
}
return atmosphere.subscribe(result);
}
}
})(window.angular);
if (responseParameterDelegateFunctions.indexOf(property) >= 0)
is missing its curly braces?
if (responseParameterDelegateFunctions.indexOf(property) >= 0) {
result[property] = function (response) {
$rootScope.$apply(function () {
r[property](response);
});
};
}
else if (property === 'onTransportFailure') {
result.onTransportFailure = function (errorMsg, request) {
$rootScope.$apply(function () {
r.onTransportFailure(errorMsg, request);
});
};
}
else if (property === 'onReconnect') {
result.onReconnect = function (request, response) {
$rootScope.$apply(function () {
r.onReconnect(request, response);
});
};
}
N.B: I'm pretty much new to angularJS programming. What I'm trying to do is, to save info returned by a service to an object. My object looks like this.
var userObject = {
"id": "1",
"firstName": "Amelia",
"lastName": "Earheart"
};
I have a factory that returns data from back end and it looks like this:
.factory('myService', function($http) {
var baseUrl = 'backendservice/';
return {
myInfo:function() {
return $http.get(baseUrl + 'getmyInfo');
}
};
})
And this is how my Controller communicates with the factory service:
.controller('myController', function($routeParams,myService) {
var my = this;
my.basicInfo = function () {
//to get my info
myService.myInfo().success(function(data) {
my.activeUser.myData.id = data.id;
my.activeUser.myData.firstName = data.firstName;
my.activeUser.myData.lastName = data.lastName;
});
};
my.addSomething = function(post) {
var userObject = my.basicInfo();
};
});
and this is how I assign the data to userObject
var userObject = my.basicInfo();
I don't know why it's not working. Factory service runs but the value is not assigned to userObject.
My Controller as whole looks like this:
(function() {
angular
.module('myApp.spa', [])
.factory('myService', function($http) {
var baseUrl = 'backendservice/';
return {
myInfo:function() {
return $http.get(baseUrl + 'getmyInfo');
}
};
})
.controller('myController', function($routeParams,myService) {
var my = this;
my.basicInfo = function () {
//to get my info
myService.myInfo().success(function(data) {
my.activeUser.myData.id = data.id;
my.activeUser.myData.firstName = data.firstName;
my.activeUser.myData.lastName = data.lastName;
});
};
my.addSomething = function(post) {
var userObject = my.basicInfo();
};
});
})();
Your function my.basicInfo() does not return anything so the value of your variable userObject is undefined. Also if you want to use userObject on view expose it on your controller instance as my.userObject.
If you want to assign a value to userObject, do it either within the success callback of my.basicInfo() method or return a promise from the method my.basicInfo() and assign the value in then callback of the promise
Approach 1
my.basicInfo = function () {
//to get my info
var activeUser = {};
return myService.myInfo()
.then(function(response) {
angular.extend(activeUser, response.data);
my.userObject = activeUser;
});
};
Approach 2
my.basicInfo = function () {
//to get my info
var activeUser = {};
return myService.myInfo()
.then(function(data) {
angular.extend(activeUser, response.data);
return activeUser;
});
};
my.addSomething = function(post) {
my.basicInfo()
.then(function (response) {
my.userObject = response;
});
};
Reason is my.basicInfo does not return anything and also from $http.success/failure, you can not return any value.
So in this case, following steps you would have to do:
Define var userObject at the top of your controller so that can be accessible to all the methods.
Assign data to userObject inside success callback of $http
(function() {
angular
.module('myApp.spa', [])
.factory('myService', function($http) {
var baseUrl = 'backendservice/';
return {
myInfo:function() {
return $http.get(baseUrl + 'getmyInfo');
}
};
})
.controller('myController', function($routeParams,myService) {
var my = this;
var userObject;
my.basicInfo = function () {
//to get my info
myService.myInfo().success(function(data) {
my.activeUser.myData.id = data.id;
my.activeUser.myData.firstName = data.firstName;
my.activeUser.myData.lastName = data.lastName;
userObject = data;
});
};
my.addSomething = function(post) {
my.basicInfo();
};
});
})();
.factory('UserInfo', function($resource, apiHost) {
return $resource(apiHost + '/userinfo/:userId');
});
.controller('myController', function($routeParams,UserInfo) {
var vm = this;
// suppose that you have stored the userId somewhere after the login
vm.userObject = {};
var myUserInfo = UserInfo.get({
userId: userId
});
vm.refreshData = function (){
myUserInfo.$promise
.then(function(response) {
vm.userObject = response;
}, function(error) {
// doSomething
});
};
vm.update = function(){
myUserInfo.save(vm.userObject, function() {
// console.log('success');
}, function(error) {
// console.log('error');
});
};
});
I have this:
app.factory('contacts', function ($rootScope, $q, cordovaReady) {
return {
find: cordovaReady(function (filter) {
var deferred = $q.defer();
var options = new ContactFindOptions();
options.filter = filter;
options.multiple = true;
var fields = ["displayName", "name", "addresses", "emails"];
navigator.contacts.find(fields, function (contacts) {
$rootScope.$apply(function () {
deferred.resolve(contacts);
});
}, function (error) {
$rootScope.$apply(function () {
deferred.reject(error);
});
}, options);
return deferred.promise;
})
};
and
app.factory('cordovaReady', function () {
return function (fn) {
var queue = [];
var impl = function () {
queue.push(Array.prototype.slice.call(arguments));
};
document.addEventListener('deviceready', function () {
queue.forEach(function (args) {
fn.apply(this, args);
});
impl = fn;
}, false);
return function () {
return impl.apply(this, arguments);
};
};
});
Whenever I call from the controller:
var contactSearch = '';
contacts.find(contactSearch).then(function (contacts) {
$scope.contacts = contacts;
}, function (error) {
console.log(error);
});
I get:
ReferenceError: ContactFindOptions is not defined
at Object.<anonymous>
I made sure to wrap the function with cordovaReady. Why is this happening?
Can you go through this answer -
Uncaught ReferenceError: ContactFindOptions is not defined
Also make sure that your app.js should be included after cordova.js or phonegap JS in index.html.
I also suggest use ng-cordova wrapper for contact plugin.
include ng-cordova.js before your js in index file.
Inject ngCordova to your app module.
Inject $cordovaContacts to your service/factory.
For more visit http://ngcordova.com/
Ex.
var services = angular.module("services", ['ngCordova']);
services.service('contact', contact);
function contact($cordovaContacts, $q) {
return {
find : function() {
var deferred = $q.defer();
var options = {};
options.filter = "";
options.multiple = true;
$cordovaContacts.find(options).then(function(contacts) {
for (var i = 0; i < contacts.length; i++) {
if (null != contacts[i].phoneNumbers) {
for (var j = 0; j < contacts[i].phoneNumbers.length; j++) {
alert(contacts[i].phoneNumbers[j].value);
if (null != contacts[i].emails) {
alert(contacts[i].emails[0].value);
}
alert(contacts[i].displayName);
}
}
deferred.resolve();
}, function(err) {
deferred.reject();
alert("error in contact find");
});
return deferred.promise;
};
};
Hope this answer help you.