Reading $Cookies in AngularJS from a method - javascript

I am really new with AngularJS and I have been working in an example for few days
https://github.com/cornflourblue/angular-registration-login-example. The thing is that im trying to read a cookie that i sent from server, and in that example the angular-cookie library is so old like (1.2) so i replaced it with the newest one. The problem comes when im trying to access to the run method, i've no access to $cookies var, i tried to inject it without injecting.
I actually have no idea what's happening. So if you could help me a bit (&& ||) recommend me newest and nicer examples would be awesome.
(function () {
'use strict';
var app = angular
.module('app', ['ngRoute', 'ngCookies'])
.config(config)
.run(run);
config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'AngularJS/home/home.view.html',
controllerAs: 'vm'
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'AngularJS/login/login.view.html',
controllerAs: 'vm'
})
.when('/register', {
controller: 'RegisterController',
templateUrl: 'AngularJS/register/register.view.html',
controllerAs: 'vm'
})
.otherwise({ redirectTo: 'AngularJS/login' });
}
run.$inject = ['$rootScope', '$location', '$http'];
function run($rootScope, $location, $http, $cookies) {
//I want to use $cookies here, but i canno't seem a possible way.
// keep user logged in after page refresh
$rootScope.globals = $cookies.get('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
}
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// redirect to login page if not logged in and trying to access a restricted page
var restrictedPage = $.inArray($location.path(), ['/login', '/register']) === -1;
var loggedIn = $rootScope.globals.currentUser;
if (restrictedPage && !loggedIn) {
$location.path('/login');
}
});
}
})();
Sorry for my poor skills in English... (Not my mothertoungue) :ยท)
Thanks alot.

You forgot to add $cookies to the run.$inject array.
Moreover, defining .$inject arrays is optional as long as you use the standard dependencies names in your component functions' parameters. Here removing your .$inject definitions should leave you with a lighter and functional application.

Related

How to re-direct to state based on flag using AngularJs?

I have userAccess flag in controller if it returns false i want hide all the application from user and redirect user to access.html with some access required form So with below code it throws error transition superseded, Any idea how to achieve this task with angularjs ui.router ?
mainCtrl.js
$scope.cookie = $cookies.get(jklHr');
var parts = $scope.cookie.split("|");
var uidParts = parts[7].split(",");
$scope.newUser._id = uidParts[0];
var userAccess = AuthService.getCurrentUser($scope.newUser._id);
if(!userAccess) {
console.log("Access Deinied");
$state.go('app.access');
}
app.js
angular.module('App', [
'ui.router',
'ui.bootstrap',
'ui.bootstrap.pagination',
'ngSanitize',
'timer',
'toastr',
'ngCookies',
]).config(function($stateProvider, $httpProvider, $urlRouterProvider) {
'use strict'
$urlRouterProvider.otherwise(function($injector) {
var $state = $injector.get('$state');
$state.go('app.home');
});
$stateProvider
.state('app', {
abstract: true,
url: '',
templateUrl: 'web/global/main.html',
controller: 'MainCtrl'
})
.state('app.home', {
url: '/',
templateUrl: 'view/home.html',
controller: 'MainCtrl'
})
.state('app.dit', {
url: '/dit',
templateUrl: 'view/partials/logs.html',
controller: 'LogsCtrl',
resolve: {
changeStateData: function(LogsFactory) {
var env = 'dit';
return LogsFactory.resolveData(env)
.then(function(response) {
return response.data
});
}
}
})
.state('app.access', {
url: '/access',
templateUrl: 'view/partials/access.html',
controller: 'AccessCtrl'
});
});
Create an interceptor, all http class will go thrown the interceptor. Once the "resolve" piece is executed and return 401 you can redirect to the login screen or 403 to the forbidden view.
https://docs.angularjs.org/api/ng/service/$http
The problem is that you are trying to change a state while a previous state change is still in course.
The ui-router has events for when a state change starts and ends.
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
});
So your redirect should be in there. Anyway I recommend you move that user check to a higher level in your app, like .run(), with some exception for the login states. That way you won't have to check in every controller individually.
Make sure you've most updated version of angularjs & angular-ui. If you're using older version then check compatibility of angular-ui version with your angular version. https://github.com/angular-ui/ui-router/issues/3246
If that doesn't work, add following line inside app.config
$qProvider.errorOnUnhandledRejections(false)
don't forget add dependency $qProvider in config function.

I had created js (angular js code) file, but this js file not allowing to work other javascript components

I had created js (angular js code) file like below, but this js file not allowing to work other Javascript components.
'use strict';
// declare modules
angular.module('Authentication', []);
angular.module('Home', []);
angular.module('BasicHttpAuthExample', [
'Authentication',
'Home',
'ngRoute',
'ngCookies'
])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/login', {
controller: 'LoginController',
templateUrl: 'modules/authentication/views/login.html',
hideMenus: true
})
.when('/home', {
controller: 'HomeController',
templateUrl: 'modules/home/views/home.html'
})
.when('/component1', {
controller: 'ComponentsController',
templateUrl: 'modules/home/views/components/component1.html'
})
.when('/databaseconfig',{
controller: 'DatabaseConfigController',
templateUrl: 'modules/home/view/components/databaseConfig.html'
})
.otherwise({ redirectTo: '/login' });
}])
When ('/component1', { controller: 'ComponentsController', templateUrl: 'modules/home/views/components/component1.html' })
let us say in component1.html file, I am using ng-show/ng-hide is not working. If I use jquery components like hide/show the div based on the radio button is not working. When I am not importing above mentioned js file in component1.html then jquery (hide/show div based on radio button) angularjs (ng-show/ng-hide) components are working.
.run(['$rootScope','$location','$cookieStore','$http',
function ($rootScope, $location, $cookieStore, $http) {
// keep user logged in after page refresh
$rootScope.globals = $cookieStore.get('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
}
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// redirect to login page if not logged in
if ($location.path() !== '/login' && !$rootScope.globals.currentUser) {
$location.path('/login');
}
});
}]);

Angularfire ngRoute/resolve issue, jumps to otherwise

I'm using the latest Angular + Firebase and trying to set up a login authorization system. I have home.html which contains login+signup links, going to login.html and adding credentials works just fine (logging correct UID when submittet) but it's supposed to route to dash.html but goes back to home.html.
I've figured out that it seem to be issues with my resolve functions because the problem disappears when I remove .otherwise. But I still want (need?) it there I think.
If I'm logged in (but redirected to home.html) I can still access dash.html through the URL and I cannot access it again if I use the logout function at dash.html and that's how it should be.
But I can't figure out why I'm redirected to home.html in the first place.
Here's some of the code, any help appreciated:
My .run, .config and routes.
app.run(['$rootScope', '$location',
function($rootScope, $location){
$rootScope.$on('$routeChangeError',
function(event, next, previous, error){
if(error === 'AUTH_REQUIRED'){
$location.path('/home');
}
});
}]);
app.config(['$routeProvider', '$locationProvider', function($routeProvider,
$locationProvider){
$routeProvider
.when('/home', {
templateUrl: '/home.html',
controller: 'homeController'
})
.when('/login', {
templateUrl: '/login.html',
controller: 'loginController',
resolve: {
'currentAuth': ['Auth', function(Auth){
return Auth.$waitForAuth();
}]
}
})
.when('/dash', {
templateUrl: '/dash.html',
controller: 'dashController',
resolve: {
'currentAuth': ['Auth', function(Auth){
return Auth.$requireAuth();
}]
}
})
.otherwise({ redirectTo: '/home' });
}]);
My login controller:
app.controller('loginController', ['currentAuth', '$scope', '$firebaseAuth',
'Auth', '$location', '$rootScope',
function(currentAuth, $scope, $firebaseAuth, Auth, $location, $rootScope){
var ref = new Firebase('https://url.firebaseio.com');
$scope.auth = $firebaseAuth(ref);
$scope.loginUser = function(){
$scope.auth = Auth;
$scope.auth.$authWithPassword({
email:$scope.email,
password:$scope.password
}, {
remember: 'sessionOnly'
}).then(function(authData) {
console.log('Logged in as: ', authData.uid);
$scope.auth.$onAuth(function(authData) {
$rootScope.auth = true;
$scope.auth = Auth;
$location.path('/dash.html');
})
}).catch(function(error) {
console.log('There was an error: ', error);
});
};
}]);
And my factory and module:
var app = angular.module('app', ['firebase', 'ngRoute']);
app.factory('Auth', ['$firebaseAuth',
function($firebaseAuth){
var ref = new Firebase('https://url.firebaseio.com');
return $firebaseAuth(ref);
}]);
it has with your resolve issue.
If you look at the documentation firebase doc
you will see that they use the
$waitForSignIn
or
$requireSignIn
functions. I know that because I have done the same thing. Try that instead and it should work

how do I set up my angularjs controller

I'm just messing around with angular a bit and I built a simple task API. This api has assigned and accepted tasks. Now when building the app I have these routes:
TaskManager.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/:username/assigned-tasks', {
templateUrl: 'app/partials/assigned-tasks.html',
controller: 'TaskController'
}).
when('/:username/accepted-tasks', {
templateUrl: 'app/partials/assigned-tasks.html',
controller: 'TaskController'
}).
otherwise({
redirectTo: '/'
});
}]);
And here is the task controller I started building and then realized this was not going to work
TaskManager.controller('TaskController', ['$scope', 'AssignedTasksService', function($scope, AssignedTasksService)
{
$scope.tasks = [];
loadAssignedTasks();
function applyRemoteData( Tasks ) {
$scope.tasks = Tasks;
}
function loadAssignedTasks() {
AssignedTasksService.getAssignedTasks()
.then(
function( tasks ) {
applyRemoteData( tasks );
}
);
}
}]);
The getAssignedTasks funciton is just a function that runs a http get request to the api url and either returns and error or the api data
now as you can see the assigned tasks are automatically loaded once it hits the TaskController which is obviously a problem since I need to also be able to get accepted tasks. Now do I need to create a separate controller for accepted tasks or is there a way for maybe me to check the url from the controller and from there I can decide if I want to run the loadAssignedTasks function or the loadAcceptedTasks (which I haven't created yet). but it would just do the same thing as the loadAssignedTasks function but for the accepted tasks
As mentioned in the comments there are multiple ways to solve. All depending on current use case. But you should probably use seperate controllers to solve this problem. Also inject the data(tasks) into the controller rather than fetching them inside the controller. Consider the following example:
var resolveAssignedTasks = function(AssignedTasksService) {
return AssignedTasksService.getAssignedTasks();
};
var resolveAcceptedTasks = function(AcceptedTasksService) {
return AcceptedTasksService.getAcceptedTasks();
};
TaskManager.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/:username/assigned-tasks', {
templateUrl: 'app/partials/assigned-tasks.html',
controller: 'TaskController',
resolve: {
tasks: resolveAssignedTasks
}
}).
when('/:username/accepted-tasks', {
templateUrl: 'app/partials/assigned-tasks.html',
controller: 'TaskController',
resolve: {
tasks: resolveAssignedTasks
}
}).
otherwise({
redirectTo: '/'
});
}]);
Controllers:
TaskManager.controller('AssignedTaskController', ['$scope', 'tasks', function($scope, tasks)
{
$scope.tasks = tasks;
}]);
TaskManager.controller('AcceptedTaskController', ['$scope', 'tasks', function($scope, tasks)
{
$scope.tasks = tasks;
}]);
You could also by doing this use a single controller by merging the resolveFunctions into one function that returns the appropriate tasks depending on the current route. Hope this helps.

opening a modal in a route in AngularJS with angular-ui-bootstrap

I am trying to do what was essentially answered here Unable to open bootstrap modal window as a route
Yet my solution just will not work. I get an error
Error: [$injector:unpr] Unknown provider: $modalProvider <- $modal
My app has the ui.bootstrap module injected - here is my application config
var app = angular.module('app', ['ui.router', 'ui.bootstrap','ui.bootstrap.tpls', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
// Gets executed during the provider registrations and configuration phase. Only providers and constants can be
// injected here. This is to prevent accidental instantiation of services before they have been fully configured.
.config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
// UI States, URL Routing & Mapping. For more info see: https://github.com/angular-ui/ui-router
// ------------------------------------------------------------------------------------------------------------
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
.state('transactions', {
url: '/transactions',
templateUrl: '/views/transactions',
controller: 'TransactionsCtrl'
})
.state('login', {
url: "/login",
templateUrl: '/views/login',
controller: 'LoginCtrl'
})
.state('otherwise', {
url: '*path',
templateUrl: '/views/404',
controller: 'Error404Ctrl'
});
$locationProvider.html5Mode(true);
}])
I have reduced my controller to the following:
appControllers.controller('LoginCtrl', ['$scope', '$modal', function($scope, $modal) {
$modal.open({templateUrl:'modal.html'});
}]);
Ultimately, what I am hoping to achieve is when login is required not actually GO to the login page, but bring up a dialog.
I have also tried using the onEnter function in the ui-router state method. Couldn't get this working either.
Any ideas?
UPDATE
Ok - so as it turns out, having both ui-bootstrap.js AND ui-bootstrap-tpls breaks this - After reading the docs I thought you needed the templates to work WITH the ui-bootstrap. though it seems all the plunkers only load in the ..tpls file - once I removed the ui-bootstrap file my modal works...Am i blind? or doesn't it not really say which one you need in the docs on github? -
Now i just need to figure out how to prevent my url from actually going to /login, rather than just show the modal :)
update 2
Ok, so by calling $state.go('login') in a service does this for me.
Hi I had a hard time getting through the similar problem.
However, I was able to resolve it.
This is what you would probably need.
app.config(function($stateProvider) {
$stateProvider.state("managerState", {
url: "/ManagerRecord",
controller: "myController",
templateUrl: 'index.html'
})
.state("employeeState", {
url: "empRecords",
parent: "managerState",
params: {
empId: 0
},
onEnter: [
"$modal",
function($modal) {
$modal.open({
controller: "EmpDetailsController",
controllerAs: "empDetails",
templateUrl: 'empDetails.html',
size: 'sm'
}).result.finally(function() {
$stateProvider.go('^');
});
}
]
});
});
Click here for plunker. Hope it helps.
I'm working on something similar and this is my solution.
HTML code
<a ui-sref="home.modal({path: 'login'})" class="btn btn-default" ng-click="openModal()">Login</a>
State configuration
$stateProvider
// assuming we want to open the modal on home page
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
// create a nested state
.state('home.modal', {
url: ':path/'
});
Home controller
//... other code
$scope.openModal = function(){
$modal.open({
templateUrl: 'path/to/page.html',
resolve: {
newPath: function(){
return 'home'
},
oldPath: function(){
return 'home.modal'
}
},
controller: 'ModalInstanceController'
});
};
//... other code
Finally, the modal instance controller.
This controller synchronizes the modal events (open/close) with URL path changes.
angular.module("app").controller('ModalInstanceController', function($scope, $modalInstance, $state, newPath, oldPath) {
$modalInstance.opened.then(function(){
$state.go(newPath);
});
$modalInstance.result.then(null,function(){
$state.go(oldPath);
});
$scope.$on('$stateChangeSuccess', function () {
if($state.current.name != newPath){
$modalInstance.dismiss('cancel')
}
});
});
You may create a state with the same templateUrl and controller as your page where you want to show the modal, adding params object to it
$stateProvider
.state('root.start-page', {
url: '/',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl'
})
.state('root.login', {
url: '/login',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl',
params: {
openLoginModal: true
}
})
And in controller of the page, use this parameter to open the modal
.controller("StartPageCtrl", function($scope, $stateParams) {
if ($stateParams.openLoginModal) {
$scope.openLoginModal();
}
I found a handy hint to get this working. There are probably caveats, but it works for me. You can pass a result still but I have no need for one.
Using finally instead of the then promise resolve sorted this for me. I also had to store the previous state on rootScope so we knew what to go back to.
Save previous state to $rootScope
$rootScope.previousState = 'home';
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams){
$rootScope.previousState = from.name;
})
State using onEnter
$stateProvider.state('contact', {
url: '/contact',
onEnter: function ($state, $modal, $rootScope){
$modal.open({
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
}).result.finally(function(){
$state.go($rootScope.previousState);
})
}
});

Categories

Resources