I am using angularjs 1.5.7 and keep getting below error:
angular.min.js:117 Error: [$injector:unpr] http://errors.angularjs.org/1.5.7/$injector/unpr?p0=ngTableProvider%20%3C-%20ngTable%20%3C-%20CustomerBuyController at Error (native)
The following are what I have done
**index.html**
<html ng-app="myapp">
<head>
<link href="css/vendor/ng-table.min.css" rel="stylesheet">
</head>
<body>
...
<script src="js/vendor/jquery-2.2.4.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-2.2.4.min.js"><\/script>')</script>
<script src="js/vendor/bootstrap.min.js"></script>
<script src="js/vendor/angular.min.js"></script>
<script src="js/vendor/angular-route.min.js"></script>
<script src="js/vendor/ng-table.min.js"></script>
<script src="js/app/controller-customer-buy.js"></script>
</body>
</html>
**app.js**
var app = angular.module('myapp',["ngRoute", "ngTable"]);
**route.js**
angular.module('myapp').config(function($routeProvider, $locationProvider, $httpProvider) {
var checkLoggedin = function($q, $timeout, $http, $location, $rootScope){
// Initialize a new promise
var deferred = $q.defer();
if(!sessionStorage.getItem('userToken')) {
$location.url('/login');
deferred.resolve();
} else {
$http({
method: 'POST',
url: 'http://127.0.0.1:8008/is-valid-user-token',
data: {
token: sessionStorage.getItem('userToken')
}
}).then(function successCallback(response) {
$location.url('/buy');
deferred.resolve();
}, function errorCallback(response) {
$location.url('/login');
deferred.reject();
});
}
return deferred.promise;
};
$httpProvider.interceptors.push(function($q, $location) {
return {
response: function(response) {
// do something on success
return response;
},
responseError: function(response) {
if (response.status === 401)
$location.url('/login');
return $q.reject(response);
}
};
});
$routeProvider
.when('/', {
templateUrl : 'pages/home.html'
})
.when('/login', {
templateUrl : 'pages/login.html',
controller : 'LoginController',
resolve: {
loggedin: checkLoggedin
}
})
.when('/buy', {
templateUrl : 'pages/customer-buy.html',
controller : 'CustomerBuyController',
resolve: {
loggedin: checkLoggedin
}
})
.otherwise({redirectTo: '/'});
}).run(function($rootScope, $http, $location){
// ......
});
**controller-customer-buy.js**
(function () {
'use strict';
angular.module('myapp').controller('CustomerBuyController',
['$rootScope', '$scope', '$parse', '$http', 'ngTable' ,function($rootScope, $scope, $parse, $http, ngTable) {
});
})();
Related
I'm getting an error saying,
[$injector:unpr] http://errors.angularjs.org/1.4.1/$injector/unpr?p0=qProvider%20%3C-%20q%20%3C-%20searchResult
When I use the following config and controller. I'm trying to resolve and http request on a specific route.
.when('/fsr/:first', {
templateUrl: 'views/fsr.html',
controller: 'fsrCtrl',
resolve: {
searchResult: ['$http', 'q', function($http, $q) {
var def = $q.defer();
var samples;
$http.get('/api/fsr').success(function(data, status){
samples = data;
def.resolve(data);
})
return {
getSamples: function() {
return def.promise;
}
}
}]
}
})
.controller('fsrCtrl', ['$scope', 'searchResult', function($scope, searchResult){
searchResult.getSamples().then(function(data){
console.log(data);
})
}])
Why I'm getting this?
Here are the solution, change q to $q.
searchResult: ['$http', '$q', function($http, $q) {
...
}
var app = angular.module('webbapp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
console.log('woot');
$routeProvider
.when('/fsr', {
templateUrl: 'fsr.html',
controller: 'fsrCtrl',
resolve: {
searchResult: ['$http', '$q', function($http, $q) {
var def = $q.defer();
var samples;
$http.get('/api/fsr').success(function(data, status){
samples = data;
def.resolve(data);
})
return {
getSamples: function() {
return def.promise;
}
}
}]
}
})
}])
.controller('fsrCtrl', ['$scope', 'searchResult', function($scope, searchResult){
searchResult.getSamples().then(function(data){
console.log(data);
})
}])
angular.bootstrap(document, ['webbapp']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello Plunker!</h1>
Load Fsr view
<div ng-view=""></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-route.min.js"></script>
<script src="app.js"></script>
</body>
</html>
All works fine if I don't inject into controller "getChildrenNumber", after then I get the error from $injector.
I've read even this https://docs.angularjs.org/error/$injector/unpr, but it seems not be one of that cases
HTML (index.html):
<html class="no-js" ng-app="myApp" ng-strict-di>
.
.
.
<script src="jsLib/angular_v1.4.js" type="text/javascript"></script>
<script src="jsLib/angular-ui-router.min.js" type="text/javascript"></script>
<script src="jsLib/angular-ui-router-statehelper.min.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<script src="routes.js" type="text/javascript"></script>
routes.js:
var config = ["$urlRouterProvider", "$stateProvider", "$locationProvider", function($urlRouterProvider, $stateProvider, $locationProvider){
$urlRouterProvider.otherwise("/multi");
$stateProvider
.state("multi",{
url: "/multi",
views: {
"": {
templateUrl: "multipleView.htm",
controller: "MainCTRL",
controllerAs: "ctrl"
},
"viewA#multi": {
templateUrl: "testingBlock.htm",
controller: "MainCTRL",
controllerAs: "ctrl"
},
"viewB#multi": {
templateUrl: "app/templates/login.htm",
controller: ["$scope", "getChildrenNumber", function($scope, getChildrenNumber){
$scope.nameApp = "nameAppChanged";
$scope.children = getChildrenNumber + " Miao";
}]
}
},
resolve: {
getChildrenNumber: ["$http", function($http){
return "Some response from an API";
}]
}
});
}];
angular
.module("myApp")
.config(config);
app.js:
angular
.module("myApp", ["ui.router"])
.controller("MainCTRL", ["$scope", "getChildrenNumber", function($scope, getChildrenNumber){
this.nameApp = "myApp";
$scope.children = getChildrenNumber;
}]);
You are implementing it the wrong way..
Firstly, in routes.js
$stateProvider
.state("multi",{
url: "/multi",
views: {
// Views Code here //
},
resolve: {
getChildrenNumber: getChildrenNumber
}
});
}];
then you have to create your factory:
angular.module('myApp')
.factory('children', ['$http', function ($http) {
return {
getChildrenNumber: getChildrenNumber
};
function getChildrenNumber() {
return "Some response from an API";
}
}]);
After this you can inject it in your controller as children
This question comes from another one: AngularJS - Determine if the view should be displayed by an ajax call result upon the route changes
As to my previous question, finally I came to this solution:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", checkLoginController);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider'];
function routeConfigurator($routeProvider, $locationProvider) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", function checkPermit($q, userFactory, $location) {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({
message: "Proceed to change route."
});
}
else {
deferred.reject({
message: "Redirect to the default page."
});
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}]
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", function checkPermit($q, userFactory, $location) {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({
message: "Proceed to change route."
});
}
else {
deferred.reject({
message: "Redirect to the default page."
});
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}]
}
});
// ...
}
})();
However, I have repeated the same piece of code for each route I would like to forbid undesired access. So now my question is how to do it once for all. I have tried the code as below:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", checkLoginController);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider'];
function routeConfigurator($routeProvider, $locationProvider) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", checkPermit]
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", checkPermit]
}
});
// ...
}
function checkPermit($q, userFactory, $location) {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({
message: "Proceed to change route."
});
}
else {
deferred.reject({
message: "Redirect to the default page."
});
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}
})();
And it doesn't work, I got error saying: defer is not defined, something like that. Then I used a factory to wrap that piece of logic:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", checkLoginController)
.factory('checkPermit', checkPermitFactory);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider', 'checkPermit'];
checkPermitFactory.$inject = ['$q', '$location', 'userFactory'];
function routeConfigurator($routeProvider, $locationProvider, checkPermit) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
// ...
}
function checkPermitFactory($q, userFactory, $location) {
function checklogin() {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({ message: "Proceed to change route." });
}
else {
deferred.reject({ message: "Redirect to the default page." });
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}
var factory = {
checklogin: checklogin
};
return factory;
}
})();
And I got error saying that it could not find checkPermit provider, when investigating this problem, I realized that you just cannot inject an dependency on an stance of factory to routeConfigurator, so here I am supposed to use checkPermitProvider instead.
I am confused now.
Any help is appreciated. Thanks.
thank you all for the replies.
In the end, I found I can get it working in this way:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", ['$q', '$location', 'userFactory', function checkPermitFactory($q, userFactory, $location) {
function checklogin() {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({ message: "Proceed to change route." });
}
else {
deferred.reject({ message: "Redirect to the default page." });
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}
var factory = {
checklogin: checklogin
};
return factory;
}])
.factory('checkPermit', checkPermitFactory);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider', 'checkPermit'];
function routeConfigurator($routeProvider, $locationProvider, checkPermit) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
// ...
}
})();
I used $inject property to specify the dependencies just because that was suggested in the section 'Manually Identify Dependencies' in this article: https://github.com/johnpapa/angularjs-styleguide#manually-identify-dependencies.
And honestly I don't quite understand how does $inject work exactly though; I just got the concerns behind that. So this problem has been solved, but I don't know the difference between the two ways of defining a controller and declaring there dependencies.
I have a problem with the provider in AngularJS.
I would like to in any view to check whether the user is logged on. If not then it should redirect to / login. On the console, there is no error. I do not know what is wrong.
var app= angular.module("app", ["ngRoute", "ngAnimate", "ngResource"]);
app.config(["$routeProvider", "$locationProvider", function($routeProvider, $locationProvider) {
var getItemNameById = function($route, $location, service, breadcrumbs, path) {
service.getItem($route.current.params.id).then(function(evt) {
if(evt.title) {
$route.routes[path].label = evt.title;
} else if(evt.name) {
$route.routes[path].label = evt.name;
}
breadcrumbs.generateBreadcrumbs();
}, function() {
$location.path("/404");
});
};
$routeProvider
.when("/", {
template: "",
label: "Home",
resolve: function($q, $location) {
alert("in resolve Home...");
var deferred = $q.defer();
if (!isLoggedIn) {
$location.path('/login');
}
deferred.resolve();
return deferred.promise;
}
})
.when("/patient", {
templateUrl: "patient.html",
label: "Patient",
resolve: function($q, $location) {
alert("in resolve Patient...");
var deferred = $q.defer();
if (!isLoggedIn) {
$location.path('/login');
}
deferred.resolve();
return deferred.promise;
}
})
.when("/doctor", {
templateUrl: "doctor.html",
controller: "DoctorController",
label: "Doctor",
resolve: function($q, $location) {
alert("in resolve Home...");
var deferred = $q.defer();
if (!isLoggedIn) {
$location.path('/login');
}
deferred.resolve();
return deferred.promise;
}
});
}]);
app.run(["$rootScope", "LoginService", function($rootScope, LoginService) {
LoginService.checkSession().then(function(response) {
$rootScope.isLoggedIn = response;
}, function(reject) {
$rootScope.isLoggedIn = reject;
});
}]);
why not enter into sections resolve (alert also does not show) on the home page?
best regards
I think you should set a event to route change ,something like this:
app.run(function($rootScope) {
$rootScope.$on("$routeChangeStart", function(event, nextRoute, currentRoute) {
if (nextRoute != null ) {
//Check session
}
});
});
AngulaR resolve API
The API says for resolve:
key – {string}: a name of a dependency to be injected into the controller.
#egghead, there is this video on the topic:
egghead - Angular resolve
What i do not understand is what that key object is for and why the author of the above video does inject the controller into itself
key – {string}: a name of a dependency to be injected into the
controller.
app.config(function($routeProvider) {
$routeProvider.
when('/', {
controller: 'ListCtrl',
resolve: {
myResolve: function(MyService) {
return MyService();
}
},
templateUrl:'./views/list.html'
})
});
Instead of (in the controller)
app.controller('MyController',function($scope,MyService){
$scope.data = MyService();
});
if you use resolve
app.controller('MyController',function($scope,myResolve){
$scope.data = myResolve;
});
UPDATE
a working example
<!doctype html>
<html ng-app="myModule">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="content" data-ng-view=""></div>
<script src="http://code.angularjs.org/1.0.8/angular.min.js"></script>
<script>
var myModule = angular.module('myModule', []);
myModule.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: './index.html',
controller: 'IndexCtrl',
resolve: {
hello: function(Hello) {
return Hello.getMessages();
}
}
})
.otherwise({
redirectTo: '/'
});
});
myModule.factory('Hello', function($q, $timeout) {
var getMessages = function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve('Hello');
}, 1000);
return deferred.promise;
};
return {
getMessages: getMessages
};
});
myModule.controller('IndexCtrl',function($scope,hello){
$scope.hello = hello;
});
</script>
</body>
</html>
the view
<p>{{hello}}</p>