how to connect ionic factory to webapi? - angularjs

i've been experimenting with ionic (building in online phonegap builder) and currently following this : http://mcgivery.com/ionic-using-factories-and-web-services-for-dynamic-data/
unfortunately it doesn't seem to work. i'm trying to get a user's username and compare it if it matches once i tap a button. but my app doesnt respond to taps. if there is another way to connect to webapi please do suggest. thank you.
here's my services.js code:
.factory('userService', ['$http', function($http) {
var users = [];
return {
getUsers: function(){
return $http.get("http://10.10.9.169/UserService/api/users").then
(function(response){
users = response;
return users;
});
},
getUser: function(id){
for(i=0;i<users.length;i++){
if(users[i].Username == id){
return users[i];
}
}
return null;
}
}
}])
and here is my controllers.js code:
angular.module('app.controllers', [])
.controller('LoginCtrl', ['$scope', '$stateParams',
'$location','userFactory',
function ($scope, $stateParams, $location, userFactory) {
$scope.userdata = {};
$scope.enterlogin = function(usern) {
if(userFactory.getUser(usern) != null)
{
$location.path('/page14');
}
else
{
alert('Failed');
}
}
}])

Try with this,
getUsers: function(){
return $http.get("http://10.10.9.169/UserService/api/users").then
(function(response){
users = response.data;
return users;
});
},

Related

Unable to inject one factory into another factory in angularjs 1 and send token to angularjs application

I have an application which is a php application. I want this application to reside in my primary domain (primarydomain.com purposely for Single-Sign-On(to manage account details). Every user login here and upon successful login, redirect to one of my app hosted on a first.primarydomain.com. Upon redirection, authorize the user by checking if the user really logged in.
Now I have hosted an angularjs application in first.primarydomain.com
In my angularjs project, I have created a factory file which has 2 factory
1. Data
2. Auth.
The Data is for database operation while the Auth is meant for authorization check and logging out users.
Below is my code.
App.js
/* Init global settings and run the app */
app.run(["$rootScope", "settings", "$state", "$location", "Auth", function($rootScope, settings, $state, $location, Auth) {
$rootScope.$state = $state; // state to be accessed from view
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
if (!$rootScope.authenticated || $rootScope.authenticated==false){
var user;
Auth.isLoggedIn()
user=JSON.parse(localStorage.getItem('currentUser'));
console.log(user)
if(!user){
window.location="http://primarydomain.com/login"
}else{
//this.authenticated=true;
//this.loggedUser=user;
$rootScope.authenticated = true;
$rootScope.loggedUser =user;
}
}
//console.log($state)
});
}]);
//Factory.js
//Data. factory
//do some database query
app.factory("Data", ['$http', '$location', function ($http, $q, $location) {
var serviceBase = 'server/f3';
var obj = {};
obj.get = function (q) {
//alert(q)
return $http.get(serviceBase + q).then(function (results) {
return results.data;
});
};
obj.gets = function(q,config){
return $http.get(serviceBase + q,config);
}
obj.post = function (q, object) {
return $http.post(serviceBase + q, object).then(function (results) {
return results.data;
});
};
obj.posts = function (q, object) {
return $http.post(serviceBase + q, object, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined,'Process-Data': false}
}
)
.then(function (results) {
return results.data;
})
};
obj.put = function (q, object) {
return $http.put(serviceBase + q, object).then(function (results) {
return results.data;
});
};
obj.delete = function (q) {
return $http.delete(serviceBase + q).then(function (results) {
return results.data;
});
};
return obj;
}]);
app.factory('Auth', ['$http', '$location','Data', function ($http,$location,Data){
var obj = {};
obj.isLoggedIn = function(){
var user=JSON.parse(localStorage.getItem('currentUser'));
if(!user){
Data.get('/webpass/1').then(function(datas){
if(datas.type==1){
//alert('response good')
//console.log(datas.response)
localStorage.setItem('currentUser', JSON.stringify(datas.response));
return datas.response;
}else{
return false;
}
});
}else{
//alert('deji')
return (user)?user:false;
}
};
obj.Logout= function(){
//console.log('deji')
Data.get('/logout').then(function(datas){
//console.log(datas)
if(datas.type==1){
localStorage.removeItem('currentUser');
return true;
}else{
return false;
}
});
};
return obj;
}]);
<!-- end snippet -->
//Logout controllers
app.controller('LogoutController', function($rootScope, $scope, $location, Auth) {
Auth.Logout();
var user=JSON.parse(sessionStorage.getItem('currentUser'));
if(!user){
$rootScope.authenticated=false;
$rootScope.loggedUser=null;
window.location='http://primarydomain/login';
}else{
//alert('Unable to log user out')
$location.path('/dashboard');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
In the factory, none of the factory function can call the injected factory. It actually doesn't give any error but while tracking the execution flow, I realized that it doesn't even execute that part of the factory.
Another problem is that after successful login on the primarydomain.com, I want to send a token alongside the first.primarydomain.com which contains some user information and the access details. Please, how do I do this with angularjs 1.
Please help.
Check whether you have any injection issues by changing
app.factory("Data", ['$http', '$location', function ($http, $q, $location) {
to
app.factory("Data", ['$http', '$q', '$location', function ($http, $q, $location) {
You are not returning the values from isLoggedIn function. A simpler example of how it needs to work:
return $http.get(url).then((res) => {
return res.data;
}
Notice both return used, since we also need to return a Promise as well as its value.
You have failed to return the Promise:
Data.get('/webpass/1').then(function(datas){
/* Some code here */
return datas.response;
});
Instead it should be:
return Data.get('/webpass/1').then(function(datas){
/* Some code here */
return datas.response;
});

Unknown provider error while injecting service

I am trying to inject a custom service to a controller but it give the error that unknown provider. I have attached the relevant code below kindly look in to it as its been a while I am stuck in this problem.I am following coursera's course they are also doing it in the same way but for me its not working.
var app = angular.module('tutorial', ['ngRoute','ngMaterial'])
app.service('myService',
function myService(data) {
var service = this;
service.validator = function(data) {
if (data.name.$valid)
return true
else
return false
}
// return service
}
)
app.controller('myCtrl',['$scope', '$http', '$location', 'myService', myCtrl])
function myCtrl($scope, $http, $location, myService) {
$scope.editorEnabled = false;
myService = this;
$scope.insertemployee = function(empinfo) {
if (myservice.validator(empinfo)) {
console.log(empinfo.name)
console.log(empinfo.email)
console.log(empinfo.address)
$http.post('insertEmp.php',{'name':empinfo.name, 'email': empinfo.email, 'address':empinfo.address}).then(function(data) {
console.log(data)
})
}
}

Issue with Angular.js and Angular Style Guide

I'm having an issue correctly getting a data service to work as I try to follow the Angular Style Guide (https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#data-services)
I'm sure it's something obvious to the more experienced but I can't get the data set to assign properly to the vm.items outside of the
Data Service
(function() {
'use strict';
angular
.module('portfolioApp')
.factory('portfolioService', portfolioService);
portfolioService.$inject = ['$http', 'logger'];
function portfolioService($http, logger) {
return {
getPortfolioData: getPortfolioData,
};
function getPortfolioData() {
return $http.get('./assets/portfolio/portfolioItems.json')
.then(getPortfolioDataComplete)
.catch(getPortfolioDataFail);
function getPortfolioDataComplete(response) {
return response.data;
}
function getPortfolioDataFail(error) {
logger.error('XHR Failed for getPortfolioData.' + error.data);
}
}
}
}());
Controller
.controller('portfolioController', ['$scope', '$http', '$stateParams', 'logger', 'portfolioService', function($scope, $http, $stateParams, logger, portfolioService) {
var vm = this;
vm.items = [];
activate();
function activate() {
return getData().then(function() {
logger.info('Activate the portfolio view');
});
}
function getData() {
return portfolioService.getPortfolioData()
.then(function(data) {
vm.items = data;
return vm.items;
});
}
console.log("test")
console.log(vm.items);
console.log("test")
}])
Your getData function is a promise, so it's run asynchronously. Your console.log are called before the end of the promise so the vm.items is still empty.
Try to put the log in the then callback.

Initiate a service and inject it to all controllers

I'm using Facebook connect to login my clients.
I want to know if the user is logged in or not.
For that i use a service that checks the user's status.
My Service:
angular.module('angularFacebbokApp')
.service('myService', function myService($q, Facebook) {
return {
getFacebookStatus: function() {
var deferral = $q.defer();
deferral.resolve(Facebook.getLoginStatus(function(response) {
console.log(response);
status: response.status;
}));
return deferral.promise;
}
}
});
I use a promise to get the results and then i use the $q.when() to do additional stuff.
angular.module('angularFacebbokApp')
.controller('MainCtrl', function ($scope, $q, myService) {
console.log(myService);
$q.when(myService.getFacebookStatus())
.then(function(results) {
$scope.test = results.status;
});
});
My problem is that i need to use the $q.when in every controller.
Is there a way to get around it? So i can just inject the status to the controller?
I understand i can use the resolve if i use routes, but i don't find it the best solution.
There is no need to use $q.defer() and $q.when() at all, since the Facebook.getLoginStatus() already return a promise.
Your service could be simpified like this:
.service('myService', function myService(Facebook) {
return {
getFacebookStatus: function() {
return Facebook.getLoginStatus();
}
}
});
And in your controller:
.controller('MainCtrl', function ($scope, myService) {
myService.getFacebookStatus().then(function(results) {
$scope.test = results.status;
});
});
Hope this helps.
As services in angularjs are singleton you can create new var status to cache facebook response. After that before you make new call to Facebook from your controller you can check if user is logged in or not checking myService.status
SERVICE
angular.module('angularFacebbokApp')
.service('myService', function myService($q, Facebook) {
var _status = {};
function _getFacebookStatus() {
var deferral = $q.defer();
deferral.resolve(Facebook.getLoginStatus(function(response) {
console.log(response);
_status = response.status;
}));
return deferral.promise;
}
return {
status: _status,
getFacebookStatus: _getFacebookStatus
}
});
CONTROLLER
angular.module('angularFacebbokApp')
.controller('MainCtrl', function ($scope, $q, myService) {
console.log(myService);
//not sure how do exactly check if user is logged
if (!myService.status.islogged )
{
$q.when(myService.getFacebookStatus())
.then(function(results) {
$scope.test = results.status;
});
}
//user is logged in
else
{
$scope.test = myService.status;
}
});

AngularJS - Changing a template depending to a service

I am fairly new to Angular and I find it quite difficult to think the Angular way.
I have registered a SessionService which loads a user object at login. Each controller can depend on the SessionService so I can have some sort of access control.
app.factory('SessionService',['$resource', function($resource){
var service = $resource('/session/:param',{},{
'login': {
method: 'POST'
}
});
var _user = { authorized: false };
function getUser() {
return _user;
}
function authorized(){
return _user.authorized === true;
}
function unauthorized(){
return _user.authorized === false;
}
function login(newUser,resultHandler) {
service.login(
newUser,
function(res){
_user = (res.user || {});
_user.authorized = res.authorized;
if(angular.isFunction(resultHandler)) {
resultHandler(res);
}
}
);
}
return {
login: login,
authorized: authorized,
getUser: getUser
};
}]);
...this is how I access the SessionService from a controller:
app.controller('SidebarCtrl', ['$scope', 'SessionService', function($scope, SessionService) {
$scope.template = '/templates/sidebar/public.html';
if(SessionService.authorized()){
$scope.template = '/templates/sidebar/menu.html'; // <-- ???
}
}]);
...and here the html file:
<div ng-controller="SidebarCtrl">
<div ng-include src="template"></div>
</div>
Here is my question: How do I make the SidebarCtrl's template dependent on SessionService.authorize? So the sidebar shows the right content according to a user being logged in or not.
I hope this makes sense to you.
You need to $watch the SessionService.authorized(). So change the controller as:
app.controller('SidebarCtrl', ['$scope', 'SessionService', function($scope, SessionService) {
$scope.template = null;
$scope.$watch(
function() {
return SessionService.authorized();
},
function(authorized) {
if( authorized ) $scope.template = '/templates/sidebar/menu.html';
else $scope.template = '/templates/sidebar/public.html';
}
);
}]);

Resources