Angular 1.5 Unknown provider - angularjs

So i get the:
Error: $injector:unpr
Unknown Provider
Unknown provider: canOrganiseProvider <-
i cannot figure out why, i simple have this end point which i've tested it works ok, and just want to resolve this before i navigate to a route, it does not work when trying to resolve canOrganise, any ideas why?
Thank you.
Jumping into code.
The end point.
[HttpGet]
[Route("{eventCode}/isOrganiser")]
[Audit(AuditLog.Nothing)]
public IHttpActionResult HasOrganisationalRights([FromUri] string eventCode)
{
var response = Resolve<ICanManageEventOrganisationRightsOperation>().CanOrganiseEvent(new CanManageEventOrganisationRequest
{
EventCode = eventCode,
CurrentUser = CurrentUser,
});
return CreateResponse(response, () => response.CanOrganise );
}
Angular routing:
angular.module('Events').config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/event/:event/attendees', {
templateUrl: '/Content/AngularApp/Attendees/List/Template.html',
controller: 'AttendeesController',
resolve: {
'data': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.getAttendees($route.current.params.event).then(function (response) {
return response.data;
});
}],
'canManage': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.canManage($route.current.params.event).then(function (response) {
return response;
});
}],
'canOrganise': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.isOrganiser($route.current.params.event).then(function (response) {
return response;
});
}],
'grouped': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return false;
}]
}
})
}
]);
Angular service
angular.module('Events').factory('AttendeesService', ['$http',
function ($http) {
return {
getAttendee: function (eventCode, accountName) {
return $http.get('api/events/' + eventCode + '/attendees/' + accountName + '/');
},
isOrganiser: function (eventCode) {
return $http.get('api/events/' + eventCode + '/isOrganiser');
},
}
Angular controller
angular.module('Events').controller('AttendeesController', ['$scope', '$rootScope', '$routeParams', '$location', '$filter', 'data', 'canManage', 'canOrganise',
'grouped', 'AttendeesService', 'AttendeeAdderService', 'AttendeeDeleterService', 'TrackingService', 'WatcherAdderService', 'WatcherDeleterService',
'GroupColorChangerService', 'DefaultSortingChangerService', 'AdminService',
function ($scope, $rootScope, $routeParams, $location, $filter, data, canManage, canOrganise, grouped, AttendeesService, AttendeeAdderService, AttendeeDeleterService,
TrackingService, WatcherAdderService, WatcherDeleterService, GroupColorChangerService, DefaultSortingChangerService, AdminService) {
...
$scope.isOrganiser = canOrganise;
...
}
]);
angular.module('Events', [
'ngRoute', 'ngSanitize',
'angularModalService', 'ngTagsInput'
]);

found my issue, in the routing.js file i have another route that points to same controller but different URL . did not noticed the 1st time .. so adding the provider to the correct route solved my problem.
added it here
.when('/event/:event/attendees', {
templateUrl: '/Content/AngularApp/Attendees/List/Template.html',
controller: 'AttendeesController',
resolve: {
'data': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.getAttendees($route.current.params.event).then(function (response) {
return response.data;
});
}],
'canManage': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.canManage($route.current.params.event).then(function (response) {
return response;
});
}],
'canOrganise': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.isOrganiser($route.current.params.event).then(function (response) {
return response;
});
}],
'grouped': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return false;
}]
}
})
but should have added it here
.when('/event/:event/attendees/grouped/:fieldId', {
templateUrl: '/Content/AngularApp/Attendees/List/Template.html',
controller: 'AttendeesController',
resolve: {
'data': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.getAttendeesGrouped($route.current.params.event, $route.current.params.fieldId).then(function (response) {
return response.data;
});
}],
'canManage': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.canManage($route.current.params.event).then(function (response) {
return response;
});
}],
'canOrganise': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.isOrganiser($route.current.params.event).then(function (response) {
return response;
});
}],
'grouped': function () { return true; },
}
})

For use $routeProvider you mast include ng-route module to your app module:
angular.module('yourModule', ['ngRoute'])
and add connect script in your html file:
<script src="bower_components/angular/angular.min.js"></script>
...
<script src="bower_components/angular-route/angular-route.min.js"></script>

Related

$routeProvider resolve is not getting object from promise

I am having trouble trying to get an array of objects from a promise. I have two issues. First, when the GetAccounts() gets called in the AccountService, it returns 2 objects. In the resolve, when I check the variable result, it doesn't have the 2 objects. Second, when the controller gets instantiated, it gives me this error: accounts is not defined. Can anyone tell me what I am doing wrong? Thanks in advance.
AccountService.js
app.factory('AccountService', ['$http', function ($http) {
return {
GetAccounts: function () {
return $http.get('api/Account/GetAccounts')
.then(function success(response) {
return response.data;
}, function error(response) {
return console.log("Oops!");
});
}
};
}]);
AdminController.js
app.component('admin', {
templateUrl: 'Content/app/components/admin/Admin.html',
bindings: {
accounts: '<'
},
controller: function () {
this.accounts = accounts;
}
})
route.js
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/admin', {
template: '<admin accounts="$resolve.GetAccounts"></admin>',
resolve: {
GetAccounts: ['AccountService', function (AccountService) {
var result = AccountService.GetAccounts();
return result;
}]
}
})
}]);
Make the following changes to get it works.
AdminController.js
app.component('admin', {
templateUrl: 'Content/app/components/admin/Admin.html',
bindings: {
accounts: '<'
} })
route.js
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/admin', {
template: 'template.html',
resolve: {
GetAccounts: ['AccountService', function (AccountService) {
var result = AccountService.GetAccounts();
return result;
}]
},
controller:['$scope','GetAccounts',function($scope, GetAccounts){
$scope.accounts = GetAccounts;
}]
})
}]);
template.html
<div>
<admin accounts="accounts"></admin>
</div>

Why can't i use the $http service in a route resolve?

I want to make my views show only after the initial data is fetched and i am trying to accomplish this with a route resolve, but i can't get it to work. What am i doing wrong? Also my angular skills are a bit shabby so i aplogize in advance if my question is dumb.
Application.js :
var Application = angular.module('ReporterApplication', ['ngRoute']);
Application.config(['$routeProvider', '$interpolateProvider',
function($routeProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
$routeProvider
.when('/packing/scan.html', {
templateUrl: 'packing/scan.html',
controller: 'PackingScanController',
resolve: {
initData : Application.PackingScanInit()
}
})
.when('/packing/stats.html', {
templateUrl: 'packing/stats.html',
controller: 'PackingStatisticsController'
})
etc
and here is my Scan.js file :
Application.PackingScanInit = function ($q,$timeout,$http) {
var serverData = "";
$http.get('/packing/scan.action')
.success(function(data){
serverData = data;
})
.error(function(data){
serverData = data;
});
return serverData;
}
Application.controller('PackingScanController', ['initData', '$scope', '$http', function(initData, $scope, $http) {
var packer = this;
// Message log model
packer.messageLog = [{
status : "",
message : null
}];
the files are included in this order.
service are singletons means there are initialized only one but time but if you simply return from service it will be called one time but if you return a function from service it will be called again and again .See Below Sample for working.
var app = angular.module('ajay.singhApp', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/view1', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
resolve: {
myVar: function (repoService) {
return repoService.getItems().then(function (response) {
return response.data;
});
}
}
})
.when('/view2', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/view1'
});
}]);
app.factory('repoService', function ($http) {
return {
getItems: function () {
return $http.get('TextFile.txt');
}
};
});
Try this:
Application.PackingScanInit = function ($q,$timeout,$http) {
return $http.get('/packing/scan.action')
.success(function(data){
return data;
})
.error(function(data){
return data;
});
}
Also you have to adjust your resolve to this:
resolve: {
initData : Application.PackingScanInit
}
Here is a specific working example:
(function() {
angular.module('app',['ngRoute']);
function TestCtrl($scope, initData) {
$scope.value = initData;
}
angular.module('app').config(function($routeProvider) {
$routeProvider.otherwise({
template: '`<p>Dude {{value}}</p>`',
controller: TestCtrl,
resolve: {
initData: function($http) {
return $http.get('test.json') //change to test-e.json to test error case
.then(function(resp) {
return resp.data.value; //success response
}, function() {
return 'Not Found'; // error response
});
}
}
});
});
})();
http://plnkr.co/edit/SPR3jLshcpafrALr4qZN?p=preview

AngularJS - Hook Routes Changing and Centralize the logic upon that

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.

Angularjs route resolve not populating model before loading controller

I am trying to populate my model from backend(with label and messages) before my contoller get loads. My method is working fine it connects with backend and gets the data but when I am viewing that variable in controller it is coming as undefined. My variable is "Model"
This is my route file
mainApp
.config(["$routeProvider", function ($routeProvider) {
.when(AngularRoutesFactory.AIMSAdmin.SearchBookings, {
templateUrl: aimsAdminViewBase + "Bookings/SearchBookings.html",
controller: "SearchPerioperativeBookingController",
resolve: {
"Model": function (BookingFactory) {
return BookingFactory.GetSearchModel();
}
},
requireAIMSAuthorizeUser: true
})
.otherwise({
redirectTo: AngularRoutesFactory.MainApp.BaseUrl
});
}]);
My Factory is
mainApp.factory("BookingFactory", ["$location", "MainFactory",
function ($location, MainFactory) {
bookingsFactory.GetSearchModel = function () {
bookingsFactory.MainFactory.QueryAPI(apiEndpoint + "GetSearchModel", "GET", function (response) {
bookingsFactory.SearchBookingCriteria = response;
return bookingsFactory.SearchBookingCriteria;
}, null, null, bookingsFactory.LangInfo.Message_GettingBookingModel);
}
return bookingsFactory;
}]);
And this is my controller
mainApp.controller("SearchBookingController", ["$scope", "BookingFactory", "$rootScope", "$location"
, function ($scope, BookingFactory, $rootScope, $location, Model) {
$scope.bbb = Model;
}]);
Edit:
Try handling it this way:
mainApp.config(["$routeProvider", "$q", function ($routeProvider, $q) {
.when(AngularRoutesFactory.AIMSAdmin.SearchBookings, {
templateUrl: aimsAdminViewBase + "Bookings/SearchBookings.html",
controller: "SearchPerioperativeBookingController",
resolve: {
Model: function (BookingFactory, $q) {
var deferred = $q.defer();
BookingFactory.GetSearchModel().then(
function (data) {
deferred.resolve(data);
}, function () {
deferred.reject();
}
);
return deferred.promise;
}
},
requireAIMSAuthorizeUser: true
})
.otherwise({
redirectTo: AngularRoutesFactory.MainApp.BaseUrl
});
}]);
Took guidance from #Fedaykin and came up with following working solution. Please let me know if it is wrong
I just changed my factory method and resolve function by applying $q.defer method and got it working
Changed my factory GetSearchModel method with following code
bookingsFactory.GetSearchModel = function () {
bookingsFactory.MainFactory.QueryAPI(apiEndpoint + "GetSearchModel", "GET", function (response) {
deferred.resolve(response);
}, null, null, bookingsFactory.LangInfo.Message_GettingBookingModel);
return deferred.promise;
}
What I did in route file
var bookingModel= function ($q, BookingFactory) {
var deferred = $q.defer();
BookingFactory.GetSearchModel().then(
function (data) {
deferred.resolve(data);
}, function () {
deferred.reject();
}
);
return deferred.promise;
};
bookingModel.$inject = ["$q", "BookingFactory"];
Then in resolve all I did
.when(AngularRoutesFactory.AIMSAdmin.SearchBookings, {
templateUrl: aimsAdminViewBase + "Bookings/SearchBookings.html",
controller: "SearchBookingController",
resolve: {
"Model": bookingModel
},
requireAIMSAuthorizeUser: true
})
And in controller voila I got the value
mainApp.controller("SearchBookingController", ["$scope", "InitializeMainFactory", "$rootScope", "$location", "Model"
, function ($scope, InitializeMainFactory, $rootScope, $location, Model) {
$scope.Model = Model;
}]);

forwarding in section resolve by RouteProvider to another view

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
}
});
});

Resources