Unable to call Angular Controller from Meteor template - angularjs

I have updated my Meteor project from router to Iron-router;
I have created client / server side routing using Iron-router.
After updating to the iron router I am having a issue calling the LoginController when I hit the submit button it does not go to doLogin function. I am handing all the functionality in angular.doLogin function handles the login functionality.
client side route :
Router.route('/', 'login');
Router.route('/login', function () {
this.render('login');
});
login template:
<template name="login">
<div class="login-box" ng-controller="LoginController">
<h6>
<span>Welcome!</span>
Please log in using your username and password.
</h6>
<form ng-submit="doLogin();
isClick = false" name="myform" >
<fieldset>
<input type="text" id="login-username" placeholder="Username" name="username" ng-model="username" autocomplete="off" ng-click="msg = ''">
<input type="password" id="login-password" placeholder="Password" name="password" ng-model="password" autocomplete="off">
</fieldset>
<span>{{msg.message}}</span>
<button id="but" type="submit" ng-disabled="!username || !password">log in</button>
</form>
</div>
</template>
login controller:
angular.module('RSC').controller('LoginController', function ($scope, $route, $routeParams, $location, $http, $window, $sce) {
$scope.loggedIn = $window.sessionStorage['loggedIn'] ? angular.fromJson($window.sessionStorage['loggedIn']) : {status: false};
$scope.sessionid = Meteor.createSessionId();
// Add the login method
$scope.doLogin = function () {
var username = $scope.username;
var password = $scope.password;
// Adding the login to help generate the clientId
if (!$window.localStorage['clientid_' + username]) {
$window.localStorage['clientid_' + username] = Meteor.RSCRandomNumber();
}
// Get client id from local storage
var clientid = $window.localStorage['clientid_' + username];
// build the parameters
var dataSent = {"username": username, "password": password, "clientid": clientid};
return $http({
url: '/req/login',
method: 'POST',
data: jQuery.param(dataSent),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).error(function (err) {
$scope.msg = err;
}).success(function (result) {
//resolve the promise as the data
if (!result.hasOwnProperty('info')) {
$scope.username = "";
$scope.password = "";
$scope.msg = result.error;
$window.sessionStorage['userInfo'] = JSON.stringify({});
$window.sessionStorage['loggedIn'] = JSON.stringify({status: false});
} else {
$window.sessionStorage['userInfo'] = JSON.stringify(result.info);
$window.sessionStorage['loggedIn'] = JSON.stringify({status: true});
$scope.msg = "";
Session.set("vendorId", result.info.vendorId);
$location.path("/home");
}
});
};
});

I was able to fix the issue,Following solution helped me :https://github.com/Urigo/angular-meteor/issues/48
if (Meteor.isClient) {
Router.onAfterAction(function (req, res, next) {
Tracker.afterFlush(function () {
angular.element(document).injector().invoke(['$compile', '$document', '$rootScope',
function ($compile, $document, $rootScope) {
$compile($document)($rootScope);
if (!$rootScope.$$phase)
$rootScope.$apply();
}
]);
});
});
}

Related

code for login authorization using angularjs

I am new to angularjs... i need help in writing code for login authorization with encoded credentials.. i need to do what i have done in jquery.
My jquery code is given below. using java rest services and mysql as backend.
<script type="text/javascript">
$(document).ready(function(){
$(".user_login").click(function(){
var username=$('#uname').val();
var password=$('#pass').val();
function make_base_auth(username, password) {
var tok = username + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
}
$.ajax
({
type: "POST",
url: "templates/login",
dataType: 'application/json',
beforeSend: function (xhr){
xhr.setRequestHeader("Authorization" , make_base_auth(username, password));
},
success: function(){
window.location.assign ="welcome.jsp";
},
error: function(data) {
var a = JSON.parse(data.responseText);
$("#login_msg").html("<p style='margin:3px'>" + a.message.text + "</p>");
}
});
});
});
</script>
HTML
<html ng-app="auth">
<div data-ng-controller="AuthController as vm">
// your template
<form>
<input type="text" data-ng-model="vm.username">
<input type="password" data-ng-model="vm.password">
<button data-ng-click="vm.login()">Login</button>
</form
// your template
</div>
</html>
JS auth.js
var app = angular.module('auth', []);
app.controller('AuthController', ['$scope', function($scope){
var vm = this;
vm.login = function() {
function make_base_auth(username, password) {
var tok = username + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
}
// IMPORTANT, you should move request logic to repositores,
// controller should only do stuff like:
// authService.login(vm.username, vm.password).then(...)
$.ajax
({
type: "POST",
url: "templates/login",
dataType: 'application/json',
beforeSend: function (xhr){
xhr.setRequestHeader("Authorization" , make_base_auth(vm.username, vm.password));
},
success: function(){
window.location.assign ="welcome.jsp";
},
error: function(data) {
var a = JSON.parse(data.responseText);
$("#login_msg").html("<p style='margin:3px'>" + a.message.text + "</p>");
}
});
}
}]);
Use Angular Js functionalities and API's while create web app on angularjs.
You can use jquery(include jquery library) and angularjs have some in build j query functionalities.
https://docs.angularjs.org/api/ng/function/angular.element.
var app = angular.module('exApp', []);
app.controller('authCtrl', ['$scope', 'authService', function($scope, authService){
var self = this;
self.login = function() {
authService.auth(self.username, self.password).then(function(response){
self.message = "logged in successfully";
}, function(error){
self.message = "auth failed";
});
}
}]);
app.service('authService', function($http){
this.auth = function(username, pass){
var postdata = {
method: 'POST',
url: 'templates/login',
headers: {
'Content-Type': 'application/json'
},
data: { 'username': username, 'password':pass }
};
return $http.post(postdata);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="exApp">
<div ng-controller="authCtrl as auth">
<form>
<input type="text" ng-model="auth.username">
<input type="password" ng-model="auth.password">
<button ng-click="auth.login()">Login</button>
</form>
<p style="font-size: 20px;color:red">{{auth.message}}</p>
</div>
</body>

IONIC APP- get device id for post service($http.post)

I'm trying to get the device id getUUID at the time of app login along with username and password. Is the right way to get device id and post it to the server for login.
controller.js
.controller('LoginCtrl', function($scope, $http,$rootScope,$window,$location,$cordovaDevice) {
$scope.login = function () {
var data ={
username : $scope.username,
password : $scope.password
};
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$http.post('login', data, config)
.success(function (data, status, headers, config) {
// $scope.DataResponse = data;
$location.path('#/tab/new-order');
})
.error(function (data, status, header, config) {
$window.alert("username or password incorrect");
});
console.log(device.cordova);
}
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
}
};
})
html code
<form action="" class="ki-login-form" method="post" accept-charset="utf-8">
<div class="form-group username">
<input type="text" class="form-control" name="username" value="" id="identity" placeholder="Your Name">
</div>
<div class="form-group pin">
<input type="text" class="form-control" name="password" value="" id="identity" placeholder="Your Pin">
</div>
<a type="submit" class="btns" ng-click='login()' >Login</a>
</form>
After login it has to be directed to a page href="#/tab/new-order" in the ionic tab
Add dependency injection $location in controller function like following -
.controller('LoginCtrl', function($scope, $http, $rootScope,$window,$location) {
// Your code
});
Solution for your added comment -
Use following -
Add device plugin : cordova plugin add org.apache.cordova.device
In your controller :
module.controller('MyCtrl', function($scope, $cordovaDevice) {
var uuid = $cordovaDevice.getUUID();
});
Change this
var data = $.param({
username : $scope.username,
password : $scope.password,
});
to
var data = {
username : $scope.username,
password : $scope.password,
};
UPDATE -
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log(device.cordova);
}

The data alone is missing when I try to send from Angular.js to Node.js

I am trying to send data from my Angular.js controller to Node.js backend. I succeeded in making a MongoDB entry when the request is raised.But the data is missing in the MongoDB entry. I am stuck and can't proceed with my app anymore. Can anyone give me a clear explanation why I am not able to send the form data to the Node.js.
I had put my schema of the data here:
var common = require('../common');
var inviteeSchema = common.Schema({
email: String
});
var Invite = common.conn.model('Invite', inviteeSchema);
module.exports = Invite;
I have enclosed the routing code here.
router.route('/addtoinvitelist').post(function (req, res, next) {
var invite =new Invite(req.body);
invite.save(function(err,email){
if(err) throw err;
res.json({message:"your mail id is stored in our database we will soon send you an invite"})
});
});
My HTML form goes here
<form action="#">
<div class="form-group">
<label for="subcribeNewsletter" class="control-label">INVITE FORM<br> <small>We are happy to invite you to medicoshere, So please enter your email ID in the below form.</small></label>
<div class="input-group input-group-in input-group-sm">
<div class="input-group-addon"><i class="fa fa-envelope text-belpet"></i></div>
<input class="form-control" id="subcribeNewsletter" placeholder="name#mail.com" ng-model="useremail" required>
<div class="input-group-btn">
<button type="submit" class="btn btn-default text-belpet" ng-click="AddToInviteList(useremail)"><strong>OK</strong></button>
</div>
</div>
</div><!-- /.form-group -->
</form><!-- /form -->
my angular service functions goes here
`this.AddToInviteList = function (email, cb) {
$http({
method: 'POST',
url: "http://localhost:3000/users/addtoinvitelist",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}, // set the headers so angular passing info as form data (not request payload)
data:"email"
}).success(function (data) {
console.log("email is posted sucessfully" + data);
cb(data);
})
}`
Controller function is here
App.controller('InviteController', function ($scope, $rootScope, $routeParams, $location, UserServices) {
$scope.init = function () {
console.log("hii this is a test ")
};
$scope.email = {};
$scope.AddToInviteList = function () {
UserServices.AddToInviteList($scope.email, function (dataresponse) {
console.log(dataresponse);
})
}
});
Pass email as json object { 'email' : email }.
Just try this code:
$http({
method: 'POST',
url: "http://localhost:3000/users/addtoinvitelist",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data:{ 'email' : email }
}).success(function (data) {
console.log("email is posted sucessfully" + data);
cb(data);
})
Controller :
App.controller('InviteController', function ($scope, $rootScope, $routeParams, $location, UserServices) {
$scope.init = function () {
console.log("hii this is a test ")
};
$scope.AddToInviteList = function () {
$scope.user = {
email : $scope.useremail
};
UserServices.AddToInviteList($scope.user, function (dataresponse) {
console.log(dataresponse);
})
}
});
In server side you can access the email by calling 'req.body.email'
Change your model name in HTML input element with email and send request as
$http({
method: 'POST',
url: "http://localhost:3000/users/addtoinvitelist",
headers: {
'Content-Type': 'application/json'
},
data:{ 'email' : email }
}).success(function (data) {
console.log("email is posted sucessfully" + data);
cb(data);
})
and get it at backend side as
req.body.email
I think that should work!
Update
App.controller('InviteController', function ($scope, $rootScope, $routeParams, $location, UserServices) {
$scope.init = function () {
console.log("hii this is a test ")
};
$scope.AddToInviteList = function () {
UserServices.AddToInviteList($scope.email, function (dataresponse) {
console.log(dataresponse);
})
}

How to use $q service in angular js for login?

I am new in angular js. i have making ionic app useing angular js and ionic framework,
This is my service.js file.
In this i have create LoginService for Login control. but its not working.
angular.module('starter.services', ['ngCookies'])
.service('LoginService', function ($q, $http, $cookies, $rootScope) {
return {
loginUser: function (name, pw) {
var deferred = $q.defer();
var promise = deferred.promise;
var user_data = $http.get("http://vanhalterenwatersport.nl/van/webservice/appc/login.php");
user_data.then(function (result) {
var user = result.data;
log(user);
console.log($rootScope.session);
})
function log(user) {
var i;
var isloggedin = false;
for (i = 0; i < user.length; i++) {
if (name == user[i].user_email && pw == user[i].password) {
isloggedin = true;
id = user[i].iduser;
$rootScope.session = id;
break;
}
}
if (isloggedin) {
deferred.resolve('Welcome ' + name + '!');
} else {
deferred.reject('Wrong credentials.');
}
}
promise.success = function (fn) {
promise.then(fn);
return promise;
}
promise.error = function (fn) {
promise.then(null, fn);
return promise;
}
return promise;
}
}
})
This is my controllers.js file
angular.module('starter.controllers', ['ngRoute','ngCookies'])
.controller('AppCtrl', function($scope, $ionicModal, $timeout) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
// To listen for when this page is active (for example, to refresh data),
// listen for the $ionicView.enter event:
//$scope.$on('$ionicView.enter', function(e) {
//});
})
.controller('LoginCtrl', function($scope, LoginService, $ionicPopup, $state, $cookies, $rootScope) {
$scope.data = {};
$scope.create = function () {
$state.go('signup');
}
$scope.forgot = function () {
$state.go('forgotpassword');
}
$scope.login = function () {
console.log($scope.data.user_email);
LoginService.loginUser($scope.data.user_email, $scope.data.password).success(function (data) {
var wat = $rootScope.session;
console.log(wat);
$state.go('app.dashboard');
}).error(function (data) {
var alertPopup = $ionicPopup.alert({
title: 'Login failed!',
template: 'Please check your credentials!'
});
});
}
})
This is my login.html
<ion-view view-title="Login" hide-nav-bar="true" name="login-view">
<ion-content ng-controller="LoginCtrl">
<div class="bar-header padding">
<h1 class="title vanimage"><img src='img/logo.png'></h1>
</div>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text" name="username" ng-model="data.user_email">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password" name="password" ng-model="data.password">
</label>
<label class="item">
<button class="button button-block button-positive" ng-click="login()">Log in</button>
</label>
</div>
<div class="padding">
<button class="button button-block button-positive" ng-click="create()">Registeer hier</button>
<button class="button button-block button-positive" ng-click="forgot()">Password Vergeten?</button>
</div>
</ion-content>
</ion-view>
You should put the auth logic in the backend, more secure and efficent.
This is the code I use for login in a service of a Ionic app:
login: function( loginEmail, loginPassword ) {
var deferred = $q.defer();
$http({
method: 'POST',
url: backend_url + '/auth',
// --- change content-type if needed (default = application/json)
// headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: { email: loginEmail, password: loginPassword }
}).then( function( result ) {
if( typeof result.data.token !== 'undefined' ) deferred.resolve( { token: result.data.token } );
else deferred.reject( { error: 'invalid_response' } );
}, function( result ) {
if( typeof result.data.error !== 'undefined' ) deferred.reject( { error: result.data.error, status: result.status } );
else deferred.reject( { error: 'invalid_login' } );
});
return deferred.promise;
},
$http always return a promice, so if you want to do it correctly in your service, using $q try smth like this:
var fn = function (method, url) {
var deferred = $q.defer();
$http(method, url)
.success(function (data) {
deferred.resolve(data);
}
.error(function (data, status) {
deferred.reject({
data: data,
status: status
});
});
return deferred.promise;
}
And if you want to call this function you should do
fn(method, url)
.then(
function(result){
... do if ok (resolve)
},
function( error) {
... do if error (reject)
}
)
You forgot to return the deferred object in your service..
This probably results in the following error:
Cannot read property then of undefined
I've made a basic example to demonstrate the $q service:
Controller - Login function
$scope.login = function login() {
LoginService.loginuser($scope.data.user_email, $scope.data.password)
.then(function onLoginSuccess(response) {
// response should contain 'success' data
$state.go('app.dashboard');
}, function onLoginFailed(error) {
var alertPopup = $ionicPopup.aler({
title: 'Login failed!',
template: 'Please check your credentials!'
});
});
}
Service
var API = {};
function loginUser(email, password) {
var deferred = $q.defer();
$http.get("http://vanhalterenwatersport.nl/van/webservice/appc/login.php")
.then(function onUserLoggedIn(response) {
deferred.resolve(response);
}, function onLoginFailed(error) {
deffered.reject(error);
});
// Make sure to return your promise!
return deferred.promise;
}
API.loginUser = loginUser;
Sidenote: You're also using GET in your login function. For this type of operations, you would typically POST a data-object to your back-end which on his turn will return you a result.

Authenticating the Ionic app with a backend server

I try to create with angularjs based Ionic app an authentication mechanism. The system looks like this:
mobile users are created by administrators on the backend server. The created mobile user can login into the app.
I get an Example and implemented it for my app.
constants.js
angular.module('starter')
.constant('AUTH_EVENTS', {
notAuthenticated: 'auth-not-authenticated',
notAuthorized: 'auth-not-authorized'
})
.constant('USER_ROLES', {
admin: 'admin_role',
public: 'public_role'
});
dashController.js
myApp.controller('DashCtrl', function ($scope, $state, $http, $ionicPopup, AuthService, $location, $window) {
$scope.logout = function () {
AuthService.logout();
$window.location.href = '/index.html';
};
$scope.performValidRequest = function () {
$http.get('http://localhost:8100/valid').then(
function (result) {
$scope.response = result;
});
};
$scope.performUnauthorizedRequest = function () {
$http.get('http://localhost:8100/notauthorized').then(
function (result) {
// No result here..
}, function (err) {
$scope.response = err;
});
};
$scope.performInvalidRequest = function () {
$http.get('http://localhost:8100/notauthenticated').then(
function (result) {
// No result here..
}, function (err) {
$scope.response = err;
});
};
});
loginAppController.js
myApp.controller('LoginAppCtrl', function ($scope, $state, $ionicPopup, AuthService, AUTH_EVENTS, $location, $window) {
$scope.username = AuthService.username();
$scope.$on(AUTH_EVENTS.notAuthorized, function (event) {
var alertPopup = $ionicPopup.alert({
title: 'Unauthorized!',
template: 'You are not allowed to access this resource.'
});
});
$scope.$on(AUTH_EVENTS.notAuthenticated, function (event) {
AuthService.logout();
$window.location.href = '/loginPage.html';
var alertPopup = $ionicPopup.alert({
title: 'Session Lost!',
template: 'Sorry, You have to login again.'
});
});
$scope.setCurrentUsername = function (name) {
$scope.username = name;
};
})
loginController.js
myApp.controller('LoginCtrl', function ($scope, $state, $ionicPopup, AuthService, $location, $window) {
$scope.data = {};
$scope.login = function (data) {
AuthService.login(data.username, data.password).then(function (authenticated) {
$window.location.href = '/index.html';
$scope.setCurrentUsername(data.username);
}, function (err) {
var alertPopup = $ionicPopup.alert({
title: 'Login failed!',
template: 'Please check your credentials!'
});
});
};
})
loginService.js
angular.module('starter')
myApp.service('AuthService', function ($q, $http, USER_ROLES) {
var LOCAL_TOKEN_KEY = 'yourTokenKey';
var username = '';
var isAuthenticated = false;
var role = '';
var authToken;
function loadUserCredentials() {
var token = window.localStorage.getItem(LOCAL_TOKEN_KEY);
if (token) {
useCredentials(token);
}
}
function storeUserCredentials(token) {
window.localStorage.setItem(LOCAL_TOKEN_KEY, token);
useCredentials(token);
}
function useCredentials(token) {
username = token.split('.')[0];
isAuthenticated = true;
authToken = token;
if (username == 'admin') {
role = USER_ROLES.admin
}
if (username == 'user') {
role = USER_ROLES.public
}
// Set the token as header for your requests!
$http.defaults.headers.common['X-Auth-Token'] = token;
}
function destroyUserCredentials() {
authToken = undefined;
username = '';
isAuthenticated = false;
$http.defaults.headers.common['X-Auth-Token'] = undefined;
window.localStorage.removeItem(LOCAL_TOKEN_KEY);
}
var login = function (name, pw) {
return $q(function (resolve, reject) {
if ((name == 'admin' && pw == '1') || (name == 'user' && pw == '1')) {
// Make a request and receive your auth token from your server
storeUserCredentials(name + '.yourServerToken');
resolve('Login success.');
} else {
reject('Login Failed.');
}
});
};
var logout = function () {
destroyUserCredentials();
};
var isAuthorized = function (authorizedRoles) {
if (!angular.isArray(authorizedRoles)) {
authorizedRoles = [authorizedRoles];
}
return (isAuthenticated && authorizedRoles.indexOf(role) !== -1);
};
loadUserCredentials();
return {
login: login,
logout: logout,
isAuthorized: isAuthorized,
isAuthenticated: function () {
return isAuthenticated;
},
username: function () {
return username;
},
role: function () {
return role;
}
};
})
app.js
var myApp = angular.module('starter', ['ionic', 'ngMockE2E'])
.run(function($ionicPlatform, $ionicPopup) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.run(function($httpBackend) {
$httpBackend.whenGET('http://localhost:8100/valid')
.respond({message: 'This is my valid response!'});
$httpBackend.whenGET('http://localhost:8100/notauthenticated')
.respond(401, {message: "Not Authenticated"});
$httpBackend.whenGET('http://localhost:8100/notauthorized')
.respond(403, {message: "Not Authorized"});
$httpBackend.whenGET(/.*/).passThrough();
})
.run(function ($rootScope, $state, AuthService, AUTH_EVENTS, $location, $window) {
$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 (!AuthService.isAuthenticated()) {
if (next.name !== 'login') {
event.preventDefault();
$window.location.href = '/loginPage.html';
}
}
});
})
HTML:
<ion-content style="text-align: left" ng-controller="LoginCtrl">
<span class="item item-input item-stacked-label"
style="font-weight: bold">Name and password:</span>
<label class="item item-input">
<span class="input-label">Name:</span>
<input name="name" placeholder="Name!" autofocus="true" required="true"
type="text"
ng-model="data.username"/>
</label>
<label class="item item-input">
<span class="input-label">Password:</span>
<input name="password" placeholder="Password!" required="true" type="password"
ng-model="data.password"/>
</label>
<button id="button-1" class="button button-block button-positive" ng-click="login(data)">Login</button>
</ion-content>
In a related article I get these steps as an answer:
1) Send username password to server using $http.post();
2) Server authenticates the credentials. and returns a token in return
is credentials are correct.
3) App stores this token locally and passes it to server for later
request as a mean of identification of logged in user.
Ideally you should implement SOAP or REST based services on your
server and consume those services in your app.
The example works localy. But where should change, so that I can authenticate with a user and password which stored on the backen server?

Resources