I want a route based authorization through AngularJS. I tried but wasn't able to find the right solution.
var app = angular.module('app', []);
var mycontroller = app.controller('mycontroller', function ($rootScope, authService) {
});
app.service('authService', function ($http, $rootScope) {
var userRole = ['ROLE_USER']; // this will come from database,
var userRoleRouteMap = {
'ROLE_ADMIN': [ '/dashboard', '/about-us', '/authError' ],
'ROLE_USER': [ '/usersettings', '/usersettings/personal', '/authError']
};
return {
userHasRole: function (role) {
for (var j = 0; j <= userRole.length; j++) {
if (role == userRole[j]) {
return true;
}
}
return false;
},
isUrlAccessibleForUser: function (route) {
for (var i = 0; i <= userRole.length; i++) {
var role = userRole[i];
var validUrlsForRole = userRoleRouteMap[role];
if (validUrlsForRole) {
for (var j = 0; j <= validUrlsForRole.length; j++){
if (validUrlsForRole[j] == route)
return true;
}
}
}
return false;
}
};
});
app.run(function ($rootScope) {
// This Block is not working i want to see the url change every time from here.
$rootScope.$on("$locationChangeStart", function (event, next, current) {
// handle route changes
console.log(next); // this is not working
if (!authService.isUrlAccessibleForUser("/about-us"))
$location.path('/authError');
});
});
Related
For understanding my situation, I have created plunkr. I need the callback when all async requests get executed.
Note: async functions are called recursively in the loop.
angular.module('myApp', [])
.controller("Ctrl_List", ["$scope", "$q", "$timeout", function ($scope, $q, $timeout) {
var promises = [];
$scope.result='';
$scope.runAsync = function () {
var listOfItems = [1, 2, 3, 4, 5];
$scope.result='';
// Iterating list of items.
for (var j = 0; j <= 5; j++) {
promises.push($scope.myAsyncFun(j, promises));
}
$q.all(promises).then(function () {
$scope.result+=' Chain finished!';
});
};
$scope.myAsyncFun = function (val, promises, deferred) {
if (deferred == null) {
deferred = $q.defer();
}
$timeout(function () {
$scope.result+=' Item executed: ' + val;
if (val % 2 == 0) {
for (var k = 0; k < val; k++) {
promises.push($scope.myAsyncFun(k, promises, deferred));
}
}
else {
deferred.resolve();
}
}, 1000);
return deferred.promise;
};
}]);
I have many different controllers throughout this project and all of them are declared the same way. This one now isn't getting called/giving an error and I have no clue why. I've looked through it and it all looks right to me.
I think it's probably some syntax error I'm not seeing. If its something else please tell me. I'm trying to learn angular and everything helps. Also if you need anything else just tell me.
I've made sure its not that the app.js name got changed and been looking for missing syntax but can't find anything.
https://docs.angularjs.org/error/ng/areq?p0=companyDepartmentController&p1=not%20a%20function,%20got%20undefined
company-department-controller.js
app.controller('companyDepartmentController', ['$scope', '$timeout', 'companyService', function ($scope, $timeout, companyService) {
/**
* Create/Manage Company Departments & Shifts
*
*/
// INITIALIZE VARIABLES *********************************************************************************
var vm = this;
vm.Departments = [];
vm.activeDepartment = {}
vm.departmentBeforeEdit = {};
vm.activeShift = {};
vm.OffsetString = "";
vm.SaveDepartmentSuccessMessage = null;
vm.SaveDepartmentErrorMessage = null;
// STARTUP **********************************************************************************************
(vm.GetDepartments = function () {
companyService.GetDepartmentsWithShiftInformation().success(function (data) {
console.log('hi');
for (i = 0; i < data.length; i++) {
console.log(data[i])
}
vm.Departments = data;
// for now we are limiting this to 1
vm.activeDepartment = vm.Departments[0];
vm.setTimeZoneOffsets(vm.activeDepartment);
});
})();
// move to global location? handle this better?
(vm.findLocalOffsetString = function () {
console.log('hi1');
vm.OffsetString = moment(new Date()).format('ZZ');
})();
// $BROADCAST/$ON EVENTS ********************************************************************************
// EVENTS ***********************************************************************************************
vm.saveDepartment = function (department) {
// new
if (department.DepartmentID === 0 || typeof department.DepartmentID === 'undefined') {
}
// update
else {
companyService.UpdateDepartmentHeader(department).success(function (data) {
vm.SaveDepartmentSuccessMessage = "Saved!";
resetDepartmentMessage();
department.InEdit = false
});
}
};
vm.editDepartment = function (department) {
vm.activeDepartment = department;
vm.departmentBeforeEdit = angular.copy(vm.activeDepartment);
vm.activeDepartment.InEdit = true;
};
vm.cancelDepartmentEdit = function (department) {
for (var i = 0; i < vm.Departments.length; i++) {
if (department.DepartmentID === vm.Departments[i].DepartmentID) {
vm.Departments[i] = vm.departmentBeforeEdit;
vm.departmentBeforeEdit = {};
vm.activeDepartment = vm.Departments[i];
break;
};
};
};
vm.addShift = function () {
if (!vm.activeDepartment) return;
vm.activeShift = {
DepartmentID: vm.activeDepartment.DepartmentID,
StartTime: new Date(),
LocalStartTime: new Date(new Date() + vm.OffsetString)
};
vm.activeShift.StartTime.setSeconds(0);
vm.activeShift.LocalStartTime.setSeconds(0);
};
vm.deleteShift = function (shift) {
if (!shift) return;
if (confirm("Are you sure you want to delete the shift: " + shift.Name + "?")) {
companyService.DeleteShift(shift).success(function () {
angular.forEach(vm.activeDepartment.Shifts, function (c, i) {
if (c.ShiftID === shift.ShiftID) {
vm.activeDepartment.Shifts.splice(i, 1);
};
});
});
};
};
vm.setTimeZoneOffsets = function (department) {
if (!department || !department.Shifts || department.Shifts.length === 0) return;
for (var i = 0; i < department.Shifts.length; i++) {
department.Shifts[i].LocalStartTime = new Date(department.Shifts[i].StartTime + vm.OffsetString);
department.Shifts[i].EndTime = moment(department.Shifts[i].StartTime).add(department.Shifts[i].Duration, 'hours').toDate()
};
};
var fixTimezoneOnSave = function (shift) {
shift.StartTime = new Date(shift.LocalStartTime).toLocaleString();
};
vm.setActiveShift = function (shift) {
if (!shift) return;
vm.activeShift = angular.copy(shift);
};
vm.saveShift = function (shift) {
fixTimezoneOnSave(shift);
// new shift
if (shift.ShiftID === 0 || typeof shift.ShiftID === 'undefined') {
companyService.AddShift(shift).success(function (data) {
shift.ShiftID = data;
vm.SaveDepartmentSuccessMessage = "Saved!";
resetDepartmentMessage();
getUpdatedShiftsAndInfo();
}).error(function (e) {
vm.SaveDepartmentErrorMessage = e.error;
resetDepartmentMessage();
});
}
// updating existing
else {
companyService.UpdateShift(shift).success(function (data) {
vm.SaveDepartmentSuccessMessage = "Saved!";
resetDepartmentMessage();
getUpdatedShiftsAndInfo();
}).error(function (e) {
vm.SaveDepartmentErrorMessage = e.error;
resetDepartmentMessage();
});
}
}
var getUpdatedShiftsAndInfo = function () {
companyService.DepartmentAndShiftInformation(vm.activeDepartment.DepartmentID).success(function (data) {
vm.activeDepartment.DepartmentShiftInformation = data.DepartmentShiftInformation;
vm.activeDepartment.Shifts = data.Shifts;
vm.setTimeZoneOffsets(vm.activeDepartment);
});
};
var resetDepartmentMessage = function () {
// clear error/success message if they have values still
if (vm.SaveDepartmentSuccessMessage != null) {
$timeout(function () { vm.SaveDepartmentSuccessMessage = null; }, 2000);
}
if (vm.SaveDepartmentErrorMessage != null) {
$timeout(function () { vm.SaveDepartmentErrorMessage = null; }, 2000);
}
};
// create controller object in console if we have logging turned on
if (spectrum.LoggingEnabled) {
spectrum.logController(vm);
};
}]);
_CompanyDepartment.cshtml
<div class="container-fluid" data-ng-controller="companyDepartmentController as cd">
</div>
#section scripts {
#Scripts.Render("~/bundles/companyDepartments")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/angularjs")
}
app.js
var app = angular.module('app', ['angularFileUpload', 'ngSanitize', 'ui.mask', 'ui.select', 'ui.bootstrap', 'ui.bootstrap.tpls', 'angular.filter', 'smart-table', 'colorpicker.module'])
.config(function ($httpProvider) {
//make delete type json to facilitate passing object
//to our generic method.
$httpProvider.defaults.headers["delete"] = {
'Content-Type': 'application/json;charset=utf-8'
};
});
Outside of a naming issue with the controller(which I can't see), I would imagine your issue dealing with the company-department-controller.js not being loaded.
In setting up your angular project, I would suggest that you follow this angular styleguide. It has been very helpful to me in creating a well structured project.
I am trying to work with an object array which I am sharing among two controllers one of which is dealing with modal window.
Here is the js code.
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ui.bootstrap'])
.service('Faq', function ($http) {
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
this.getFaqs = function ()
{
return this.faqList;
}
this.addfaq = function (obj) {
this.faqList.push(obj);
};
})
.controller('AppCtrl', function ($scope,$modal,Faq) {
$scope.faqData = [];
Faq.getFaqs().then(function (msg) {
$scope.faqData = msg.data;
});
}
$scope.show = function () {
$modal.open({
templateUrl: "faqAddUpdate.html",
controller: "faqctrl"
});
};
})
.controller('faqctrl', function ($scope, $modalInstance, Faq) {
$scope.question = '';
$scope.id = '';
$scope.answer = '';
$scope.editFaq = function (id) {
$scope.divFaq = true;
$scope.faqs = [];
Faq.getData().then(function (msg) {
$scope.faqs = msg.data;
var l = $scope.faqs.length;
for (var i = 0; i < l; i++) {
if ($scope.faqs[i].id == id) {
$scope.question = $scope.faqs[i].question;
$scope.id = $scope.faqs[i].id;
$scope.answer = $scope.faqs[i].answer;
}
}
});
};
$scope.AddUpdateFAQ = function () {
var faq = {
id: $scope.id,
question: $scope.question,
answer: $scope.answer
};
Faq.addfaq(faq);
console.log(faq);
$modalInstance.close();
};
$scope.Cancel = function () {
$modalInstance.dismiss();
};
});
but when I am submitting the data through the modal it says this.faqList.push is not a function.
It is because your faqList variable is not an array.
You overide the first definition:
this.faqList = [];
With this:
this.faqList = $http.get('/Json/faq.json');
But $http.get returns a promise (see doc), not an array.
You should do something like this:
this.faqList = [];
$http.get('/Json/faq.json').then(function(result) {
// process your results here
this.faqList = result.data;
});
Not tried, but this is within the function scope, so create a _this var first might help:
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
var _this = this;
this.getFaqs = function ()
{
return _this.faqList;
}
this.addfaq = function (obj) {
_this.faqList.push(obj);
};
I am using this code:
$http.get('/api/users').
success(function(data) {
$scope.authors = data;
}).
error(function() {
console.log('API error - config.')
});
And somewhere below (much bellow):
for (var i = 0; i < $scope.authors.length; i++) {
...
};
Sometimes it happens that $scope.authors are not avaliable yet. Is there any way to solve this?
UPDATE
This is the whole block structure:
// author
$http.get('/api/users').
success(function(data) {
$scope.authors = data;
processAuthors();
}).
error(function() {
console.log('API error - config.')
});
// if updating form
$scope.$on('$routeChangeSuccess', function() {
if($routeParams.id) {
$http.get('/api/offers/' + $routeParams.id).
success(function(data) {
// author
function processAuthors() {
for (var i = 0; i < $scope.authors.length; i++) {
if($scope.authors[i].email == data.author.email) {
$scope.author = $scope.authors[i];
};
};
}
Put the loop in the succes part:
$http.get('/api/users').
success(function(data) {
$scope.authors = data;
for (var i = 0; i < $scope.authors.length; i++) {
...
};
}).
error(function() {
console.log('API error - config.')
});
Yes, it doesn't matter how much below it is - you still need to call it from inside the callback because it's an async call:
function processAuthors() {
for (var i = 0; i < $scope.authors.length; i++) {
...
};
}
And then:
$http.get('/api/users').
success(function(data) {
$scope.authors = data;
processAuthors();
})
I used a function to make it look cleaner, but you can copy your code that depends on the callback inside it.
UPDATE
function processAuthors(data) {
for (var i = 0; i < $scope.authors.length; i++) {
if($scope.authors[i].email == data.author.email) {
$scope.author = $scope.authors[i];
};
};
}
$scope.$on('$routeChangeSuccess', function() {
if($routeParams.id) {
$http.get('/api/offers/' + $routeParams.id).
success(function(data) {
// author
processAuthors(data); // just call it here, define it outside
I have two angularjs function in my dataContext object that receive data from an webapi as you can see below
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId,
['common', datacontext]);
function datacontext(common) {
var service = {
getAllTagsByHttp: getAllTagsByHttp,
getBlogPostsByHttp: getBlogPostsByHttp,
getAllUserPicByHttp: getAllUserPicByHttp
};
return service;
function getAllTagsByHttp() {
return common.$http.get('/api/TagApi/alltags');
}
function getBlogPostsByHttp() {
return common.$http.get('/api/BlogPostApi/AllBlogPosts');
}
function getAllUserPicByHttp() {
return common.$http.get('/api/BlogPostApi/AllUserPic');
}
}})();
I have an angularjs controller that call these api functions from the datacontext to receive information to display back to the user. The getblogPost function is called first because the next function need's the data from this to operate on.the second function does a comparison on the first function's data to display back the img source to the user. The problem i am having is that it takes quite a few seconds for the second function to receive the data and an complete its operation. The amount of data being send back is a few records.Is there any improvements that can be made to controller or data Context object to reduce the time or improve the code?
(function () {
'use strict';
var controllerId = 'search';
angular
.module('app')
.controller(controllerId, ['common','datacontext', search]);
function search(common, datacontext) {
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
vm.title = 'search';
vm.picData = [];
activate();
function activate() {
var promises = [getBlogPosts(), getUserPicData(), getUserPicUrl()];
common.activateController(promises, controllerId)
.then(function () { log('Search View'); });
}
function getBlogPosts() {
datacontext.getBlogPostsByHttp().then(function (response) {
vm.data = response.data;
});
}
function getUserPicData() {
datacontext.getAllUserPicByHttp().then(function (response) {
vm.picData = response.data;
for (var i = 0; vm.data.length > i; i++) {
for (var x = 0; vm.picData.length > x; x++) {
if (vm.data[i].UserName == vm.picData[x].UserName) {
vm.data[i].PictureUrl = vm.picData[x].PictureUrl;
// console.log(vm.data[i].PictureUrl);
break;
}
}
}
});
}
function getUserPicUrl(username) {
getUserPicData();
for (var i = 0; vm.picData.length < i; i++) {
if (vm.picData[i].UserName === username) {
return vm.picData[i].PictureUrl;
}
}
return "not found";
}
}})();