access angular $cookies from non-angular code - angularjs

I have a test module that set cookie isTesting to be true
app.controller('test_page',
['$scope', '$window', 'userService', 'flash', '$cookies',
function($scope, $window, userService, flash, $cookies) {
helper.initCommonScope($scope, $window, userService, flash)
$scope.refreshShownHidden = function() {
$scope.showTurnOffTest = $cookies.get('isTesting')
$scope.showTurnOnTest = ! $cookies.get('isTesting')
}
$scope.turnOnTest = function() {
$cookies.put('isTesting', true)
$scope.refreshShownHidden()
helper.turnOnTest()
}
$scope.turnOffTest = function() {
$cookies.put('isTesting', false)
$scope.refreshShownHidden()
helper.turnOffTest()
}
$scope.refreshShownHidden()
}])
And in helper.js, I have
exports.havePermission = function(access, resource, userService, entity) {
//Note: In debugging, we can grant client helper all access, and test robustness of server
if (angular.$cookies.isTesting)
return true
return permission.havePermission(access, resource, userService.isAuthenticated(), entity, userService.user)
}
But $cookies is not available since helper.js is not part of any angular module, thus no DI is available. How can I access the isTesting value?
I have tried using window.isTesting instead but it's not persisted when I refresh the page or go to other pages. So cookie is a better choice

You can use Angular's injector to access Angular modules and services outside of your Angular application.
AngularJS Code
angular.module('app', ['ngCookies']).
controller('ctrl', ['$cookies', function($cookies) {
$cookies.put('isTesting', true);
}]);
Non-Angular Code
helper = {
getCookies: function() {
// Create new injector for ngCookies module
var $injector = angular.injector(['ngCookies']);
// Inject $cookies to some function and invoke it
$injector.invoke(['$cookies', function($cookies) {
alert($cookies.get('isTesting'));
}]);
}
}
HTML
<html ng-app='app'>
<head>
<script data-require="angular.js#1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script data-require="angular-cookies.js#1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-cookies.js"></script>
<script src="script.js"></script>
<script src="helper.js"></script>
</head>
<body ng-controller="ctrl">
<button onclick="helper.getCookies()">Click Me</button>
</body>
</html>
Plunker: http://plnkr.co/edit/jur9A6d69ViiJqiFgopD?p=preview

var cookies = angular.injector(['ngCookies']).get('$cookies');
It creates a new instance of $cookies service, so if you're using it across the app, it is better to export it to global.

It's not the AngularJS purpose. You should try to keep all your stuff in your AngularJS code. However you can set any global variable in AngularJS:
app.controller('test_page',
['$scope', '$window', 'userService', 'flash', '$cookies',
function($scope, $window, userService, flash, $cookies) {
angular.$cookies = $cookies;
// or window.$cookies = $cookies;
helper.initCommonScope($scope, $window, userService, flash)
Then you can access $cookies anytime anywhere. It make certain things easier but less safe (any other script can access it too, it can create conflict, etc.)

Related

angularjs new services won't work

I have an angularjs project with 6 services. Everyone of them works fine, but now if i create a new service and try to inject it, it fails. I tried to inject the same service in another project and it works.
Here is the service:
app-services/test.service.js
(function () {
'use strict';
angular
.module('app')
.factory('TestService', TestService);
TestService.$inject = ['$scope'];
function TestService($scope) {
var service = {};
service.Test = Test;
return service;
function Test() {
//Stuff
}
}
})();
Here is the controller in which i try to inject it: app-index/functions/functions.controller.js
(function () {
'use strict';
angular
.module('app')
.controller('FunctionController', FunctionController);
FunctionController.$inject = ['$scope', 'FlashService', '$location', 'UploaderService', '$q','TestService'];
function FunctionController($scope, FlashService, $location, UploaderService, $q, TestService) {
var vm = this;
var fileContainers;
$scope.UploadFile = UploadFile;
function UploadFile() {
TestService.Test();
}
}
})();
In the index.html
<script src="app.js"></script>
<script src="app-services/test.service.js"></script>
<script src="app-index/functions/functions.controller.js"></script>
Error
HTML1300: NavegaciĆ³n realizada.
localhost:44373
Error: [$injector:unpr] http://errors.angularjs.org/1.6.0/$injector/unpr?
p0=TestServiceProvider%20%3C-%20TestService%20%3C-%20FunctionController
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:44:389)
at d (https://code.angularjs.org/1.6.0/angular.min.js:42:60)
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:44:449)
at d (https://code.angularjs.org/1.6.0/angular.min.js:42:60)
at e (https://code.angularjs.org/1.6.0/angular.min.js:42:298)
at instantiate (https://code.angularjs.org/1.6.0/angular.min.js:43:242)
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:93:137)
at link (https://code.angularjs.org/1.6.0/angular-route.min.js:7:316)
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:16:45)
at ta (https://code.angularjs.org/1.6.0/angular.min.js:84:35) <div
class="ng-scope" style="width: 100%; height: 100%;" ng-view="">
As i said, the other services injected in the controller are working. And I don't think the problem is in TestService since it is working on another project.
I'm developing in Visual Studio
Edit: I removed $scope from service, but it still doesn't work
Edit 2: It looks like the problem is the caching. It loads the old version of index.html that hasn't got the reference of the new service..

ngcookies angularjs how to include module i'm using sub controller

how to inject ngCookies service to the controller . i get an error stating injection failed as below Error: [$injector:unpr] http://errors.angularjs.org/1.5.3/$injector/unpr?p0=%24cookiesProvider%20%3C-%20%24cookies%20%3C-%20Intake
app.controller("Intake", ["$scope", "$http", "$window", "$mdDialog", "$mdToast", "IntakeFactory", "fileUpload", 'ngCookies', function ($scope, $http, $window, $mdDialog, $mdToast, $Intake, $fileUpload ,$cookieStore ) {
You have to inject ngCookies not in your controller but in your module and your order of injections is incorrect.
var app= angular.module('myModuleName', ['ngCookies']);
And in your controller, you can access its properties by injecting $cookieStore like below
app.controller("Intake", ["$scope", "$http", "$window", "$mdDialog", "$mdToast", "IntakeFactory", "$fileUpload", '$cookieStore', function ($scope, $http, $window, $mdDialog, $mdToast,IntakeFactory, $fileUpload ,$cookieStore )
You can use cookie like this :
(it won't work in this snippet becuase SO doesnot allow cookies HERE)
var app = angular.module('myApp', ['ngCookies']);
app.controller('myCtrl', function($scope, $cookies) {
$cookies.putObject('cookieData', 'this is value stored by cookie');
$scope.data = $cookies.getObject('cookieData');
});
<!DOCTYPE html>
<html>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-cookies.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
{{data}}
</div>
</body>
</html>
Inject the service correctly.
Try the below one:-
angular.module('Intake', ['ngCookies']).controller('Intake', ['$cookies', function( $cookies){}])

Executing any one function in controller executes the entire controller function

I am a newbie to Angular. I am using a controller and I am initially loading the page using the init function. I have an element on html that activates the incrementPage function. When I activate the function, the init function executes again and I get the same result instead of the next page. How do I solve this issue?
myApp.controller('MusicController', ['$scope', '$resource', function($scope, $resource){
var vm = $scope;
init();
function init(){
vm.pgno = 1;
music = $resource('http://104.197.128.152:8000/v1/tracks/', {"page": vm.pgno}).get({"page": vm.pgno});
vm.tracks = music;
}
vm.incrementPage = function(){
vm.pgno = vm.pgno + 1;
console.log(vm.pgno);
music = $resource('http://104.197.128.152:8000/v1/tracks/', {"page": vm.pgno}).get({"page": vm.pgno});
vm.tracks = music;
console.log(vm.pgno);
};
}]);
Also, I am using ngRoute and two different controllers.
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: "views/listMusic.html",
controller:'MusicController',
})
.when('/genres', {
templateUrl: "views/genres.html",
controller:'MusicGenreController',
})
}]);
myApp.controller('MusicGenreController', ['$scope', 'tracklister', function($scope, tracklister) {
var vm = $scope;
var gpgno = 1;
var incrementGPage = function(){
gpgno += 1;
gen = tracklister.genreList.get({'page': gpgno});
vm.genres = gen;
}
(function(){
gen = tracklister.genreList.get({'page': gpgno});
vm.genres = gen;
})();
}]);
When I click the Genres instead of taking me to the genres view it is getting me back to the same listMusic view inside the first MusicController controller. What to do here?
<!DOCTYPE html>
<html ng-app='ListTracksApp'>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-resource.js"></script>
<script src="appl.js"></script>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
<title>Music</title>
</head>
<body>
<h1>Music Tracks</h1>
Genres
<div ng-view>
</div>
</body>
</html>
In your controller, change it to this:
myApp.controller('MusicController', ['$scope', '$resource', function($scope, $resource) {
var vm = $scope;
function $onInit() {
// the rest of your code
That'll get called once, when the controller initializes. Also I think your link is incorrect, as georgeawg pointed out but I'm not too familiar with ngRoute, I've used uiRouter for years, it should be #!/genres
One other thing although this isn't related to your question, in your init() function you have a call to your db, which I suspect is going to be async, you should probably use resolve in the ngRoute and inject it into the controller so it's initially resolved:
resolve: {
data: function ($resource) {
var url = 'http://104.197.128.152:8000/v1/tracks/';
return $resource(url, {"page": 1}).get({"page": 1}).$promise;
}
}
Then your controller can use 'data' as the result of the call:
myApp.controller('MusicController', ['$scope', '$resource', 'data', function($scope, $resource, data)

Error injecting Angular 1.4.7 cookie service

I've researched this online but cannot get it to work.
I followed this online doc below to inject the $cookies service into my login controller, but I keep getting error: [$injector:modulerr]
cookie injection
(function () {
'use strict';
angular.module('rage', ['ngCookies']).controller('LoginCtrl',
['$rootScope', '$scope', '$cookies', '$modalInstance', '$q', 'datacontext', 'userService', authenticate]);
function authenticate($rootScope, $scope, $cookies, $modalInstance, $q, datacontext, userService) {
var login = this;
// OK,CANCEL CLICK EVENTS FROM MODAL !!!
$scope.ok = function () {
var user = {userId: login.userId, pswd: login.pswd};
$modalInstance.close(user);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
})();
I've upgraded Angular from 1.3.5 to 1.4.7 and my index.html has :
<!-- jQuery and Bootstrap -->
<script src="Scripts/jquery/jquery.min.js"></script>
<script src="Scripts/plugins/jquery-ui/jquery-ui.min.js"></script>
<script src="Scripts/bootstrap/bootstrap.min.js"></script>
<!-- Angular scripts-->
<!--<script src="Scripts/angular/angular-1.3.5.min.js"></script>-->
<script src="Scripts/angular/angular-1.4.7.min.js"></script>
<script src="Scripts/angular/angular-sanitize.min.js"></script>
<script src="Scripts/angular-ui-router/angular-ui-router.min.js"></script>
<script src="Scripts/angular/angular-cookies-1.4.7.min.js"></script>
<!-- angular-ui-bootstrap -->
<!--<script src="Scripts/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>-->
<script src="Scripts/bootstrap/ui-bootstrap-tpls-0.13.0.min.js"></script>
Advice is greatly appreciated...
Bob
ngCookies is an external module: you have to include angular-cookie.js script in the index.
Apart from that, I see that you injected $modalInstance, which is probably the service from ui-bootstrap. You will have to include also angular-ui-bootstrap script, and add the module as a dependency.
To sum up, your index.html should look like:
<script src="scripts/.../angular.js"></script>
<script src="scripts/.../angular-cookie.js"></script>
<script src="scripts/.../ui-bootstrap-tpls.js"></script>
And the module declaration:
angular.module('rage', ['ngCookies', 'ui.bootstrap'])

Inject $log into every controller and service

Is there any way to inject AngularJS's $log into every service and controller? It just feels a little redundant specifying it for every one.
Another way you could do it is to add a method to the rootScope, and then access it through $scope.$root in your controllers, thus avoiding another injection. I don't know if it is as bad as globals.
testapp.js
(function(){
'use strict';
angular.module('app', [])
.run(function($rootScope, $log) {
$rootScope.log = function(msg){
$log.info(msg);
}
})
.controller('LogCtrl', ['$scope', function LogCtrl($scope) {
$scope.logThis = function(msg){
$scope.$root.log(msg);
};
}]);
})();
test.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.5/angular.min.js"></script>
<script src="testapp.js"></script>
</head>
<body ng-app="app">
<div ng-controller="LogCtrl">
<p>Enter text and press the log button.</p>
Message:
<input type="text" ng-model="message"/>
<button ng-click="logThis(message)">log</button>
</div>
</body>
</html>
Injecting it seems impossible to me without defining it in the function parameters. But you can make it available:
var $log;
app.run(['$log',function(logService) {
$log = logService;
}]);
app.controller('MainCtrl', function($scope, myService) {
$log.warn('Controlling');
});
app.service('myService', function() {
$log.warn('Ha!');
return {};
});
http://plnkr.co/edit/Zwnay7dcMairPGT0btmC?p=preview
Another way would be to set it as a global variable (window.$log), but I wouldn't do that.
Here's a solution for those who think that using the $rootscope requires too much fuss: add the $log to the angular object.
angular.module('myModule')
.run(['$log', function($log) {
angular.log = $log;
}]);
Then when you create your controllers, no $log is required.
angular.module('myModule')
.controller('MyController', MyController);
MyController.$inject = []; // <-- see, no $log required!
function MyController() {
angular.log.info("Hello world");
}
You could even take it a step further and add angular.info = $log.info if you wish to shorten it a bit more.

Resources