I am trying to create a Chrome extension for my school's Online Learning Platform. This website uses HashLocationStrategy, with multiple 'pages'.
I want to add custom ngRoutes to the page, so whenever it goes to the following URL: ".../magister/#/plus" it load my custom template into the ng-view component. I have tried the following script:
angular.module("MagisterPlusRouting", ["ngRoute"])
.controller("RootController", ($scope, $route, $routeParams, $location) => {
$scope.$route = $route;
$scope.$location = $location;
$scope.$routeParams = $routeParams;
})
.controller("PageController", ($scope, $routeParams) => {
})
.config(($routeProvider, $locationProvider) => {
$routeProvider.when("/plus", {
templateUrl: "index.html",
controller: "PageController",
});
$locationProvider.html5Mode(true);
});
But that does not seem to work, I get the following message in my console routechange undefined 0, this originates from the website's official script.
Is it even possible to do this? How do I add these new routes? If you need further information, tell me. Although I do not have access to the development source code of the website.
Related
Error: [$compile:multidir] Multiple directives [statbox, statbox] asking for template on:
(On console)
Inside index.html
<script src="js/dashboard/dashboard.module.js"></script>
<script src="js/dashboard/dashboard.component.js"></script>
<script src="js/dashboard/statbox.component.js"></script>
Inside dashboard.module.js
var dashboardModule = angular.module('dashboard', ['ngRoute']);
Inside dashboard.component.js
angular.module('dashboard').component('dashboard', {
templateUrl: 'templates/dashboard/dashboard.template.html',
controller: ['$scope', '$routeParams', '$http', '$rootScope', '$log', function DashboardController($scope, $routeParams, $http, $rootScope, $log) {
...stuff NOT REFERENCING STATBOX by any means...
}]
});
Inside statbox.component.js
angular.module('dashboard').component('statbox', {
templateUrl: 'templates/dashboard/statbox.template.html',
controller: ['$http', '$rootScope', '$log', function StatboxController($http, $rootScope, $log) {
... some random get request ...
}]
});
And inside app.js
var app = angular.module('buttonMasher', ['ngRoute', 'dashboard', ...]);
Inside dashboard.template.html
... stuff ...
<div id="history">
... stuff ...
<p><b>Statbox</b></p>
<statbox></statbox>
</div>
Inside statbox.template.html
<div id="statbox">
<p>{{$ctrl.statboxText}}</p>
What am I doing wrong and why do I get this multiple directives error?
Whenever I comment out <script src="js/dashboard/statbox.component.js"></script>
from the index.html everything works but statbox controller is not getting loaded.
(Full project is here: Github: carloworks/masher - One can clone and run spring with profile "dev" enabled.)
Error: [$compile:multidir] Multiple directives [statbox, statbox]
asking for template on
Most likely it's because you included the .js twice in your index.html and the compiler at the time of binding the directive doesn't know which template to choose.
you should check:
the compiled html page to see if you included twice statbox.js
make sure you don't have multiple spots in your code where you
define the same .component('statbox',{})
Late to the party here but in my case it happened because I stupidly named the directive the same thing as the variable that was being passed into it so when the directive was being used it was trying to recursively include itself!
I had this issue with Typescript. I renamed some ts files and visual studio (2015) kept the old generated js files. Somehow, angular used both new and old js files, and I ended up with this error. I did a clean (which deletes all generated js files), build and it worked!
Can i create several modules for routing in AngularJS app like:
1. First route management file:
angular.module('app.p.routes', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/forbidden',
{
templateUrl: 'app/views/pages/forbidden.html'
})
.......................
2. Second route management file:
angular.module('app.admin.routes', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/admin-dashboard',
{
templateUrl: 'app/views/pages/admin/dashboard.html',
controller: 'dashboardController',
controllerAs: 'dashboard'
})
.............................
3. Main app file:
angular.module('mainApp',
[
'ngAnimate', //animating
'app.p.routes', //public routing
'app.admin.routes',
'ui.bootstrap',
'ngParallax', //parallax effect
'ngFileUpload'
])
When i tried to use this approach page hangs and angular throws error:
> VM188:30554 WARNING: Tried to load angular more than once.
I need an approach to split public and admin routing management.
You can have as many AngularJS modules as you like. There are no rules against that, however, you've attempted to include the Angular source twice which is why you're seeing this warning...
> VM188:30554 WARNING: Tried to load angular more than once.
The simplest solution to your issue that I can think of, is to add an event listener to the $routeChangeStart event. With this you'll be able to verify that the current user has the correct permissions to view anything before they actually to do so.
A simple Service to store some basic information on the current user could like this.
var app = angular.module('app', ['ngRoute']);
app.service('AuthenticationService', function () {
// Set the User object
this.setUser = function () {
this.$user = user;
};
// Get the User object
this.getUser = function (user) {
return this.$user
};
});
And then upon receiving the $routeChangeStart event, you can retrieve the user object and confirm that they are allowed to proceed to the chosen resource.
Here's an example, whereupon a user needs to be an Administrator to view any route that has "/admin" in it.
app.run(function ($rootScope, $location, AuthenticationService) {
// Create a listener for the "$routeChangeStart" event
$rootScope.$on('$routeChangeStart', function () {
// Is the user is an Administrator? Are they attempting to access a restricted route?
if ($location.url().indexOf('/admin') && !AuthenticationService.getUser().isAdmin) {
// Redirect the user to the login page
$location.path('/login');
}
});
});
If you want a more advanced solution however, have a look at this: https://github.com/Narzerus/angular-permission
This will enable you to achieve a more in-depth ACL implementation across your application.
I am new to software development and am trying to build a fullstack javascript app on my own.
I currently am running a scrape with cheerio in express, as follows:
app.get('/scrape', function(req, res){
//do things.
})
I will be using Angular for the front end.
How do I do the scrape whenever a user visits my home page/root route, so that I have data to compare against their inputs in angular? assume that the home page is at '/'.
this is what my angular app.js looks like so far:
angular.module('FFTrades', [
'FFTrades.services',
'ngRoute'
]).config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'app/tradeanalyzer/tradeanalyzer.html',
controller: 'TradesController'
})
})
app.run will help you to check your url
app.run(function ($rootScope, $cookies, $location, $http) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
if (next.originalPath != '/') {
console.log('inside your home page');
}
});
});
You would want to use a .run module. These are run automatically when your app starts up.
And add your scrap data to a service or the $rootScope.
app.run(function($rootScope) {
$rootScope.hello = function() {
console.log('hello');
}
});
If you are new to angular you might run into some issues getting the result from the scrape promise and applying it to the $scope. These would be new questions, but above should answer the particular question you are looking for.
I am converting a large server rendered app to use Angular. Because of the size, we are doing it a bit at a time. During this conversion period, part of the app will use Angular and part will not. This means that routing sometimes will route within the Angular app and sometimes it will need to transition from old world to new world (easy) or new world to old world (harder).
Ideally, I would like to specifically route some page transitions within the Angular app (new world) to the proper controllers but then any other page transitions should just fetch new HTML pages (old world).
I can't seem to figure out how to do this. I think I need to use the routeProvider and when / otherwise, but there isn't a lot of documentation that I found which is helpful.
You can't use routeProvider for the old world, since angular routes only direct you within the actual same page.
You could make a placeholder angular route for each legacy route, then in the controller, inject $window and do something like:
$window.location.href = destinationUrl;
Something like: (go to the old world on logout)
app.controller('LogoutCtrl', function ($scope, $window) {
var destinationUrl = 'https://mywebsite.com/';
$window.location.href = destinationUrl;
});
Vice versa, to go back to the angular world, just use a normal link to your angular route:
Link
If you want a catch-all route to redirect to the outside, you can do the following:
otherwise({
controller: 'NotFoundCtrl'
});
...
app.controller('NotFoundCtrl', function($scope, $location, $window) {
var path = $location.path();
$window.location.href="http://test.com" + path;
})
As triggerNZ said, you can always have a controller redirect unhandled routes to the outside. Here is the HTML and Javascript showing how to do it.
HTML
<div ng-app="myApp">
<script type="text/ng-template" id="this.html">
This Page.
</script>
<script type="text/ng-template" id="that.html">
That Page.
</script>
<div>
<ul>
<li>This</li>
<li>That</li>
<li>Other</li>
</ul>
<ng-view></ng-view>
</div>
</div>
Javascript
var app = angular.module("myApp", ['ngRoute']);
app.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/this', {
templateUrl: 'this.html'
}).when('/that', {
templateUrl: 'that.html'
}).otherwise({
template: "<div></div>",
controller: function ($window, $location, $rootScope) {
if (!$rootScope.isInitialLoad) {
$window.location.href = $location.absUrl();
}
}
});
$locationProvider.html5Mode(true);
});
app.run(function ($rootScope) {
$rootScope.$on('$routeChangeSuccess', function() {
$rootScope.isInitialLoad = (typeof $rootScope.isInitialLoad === "undefined");
});
});
I'm using 'ngbp' (https://github.com/ngbp/ngbp) angular boilerplate to build my project and I'm trying to make ngProgress work to show the loader when changing from section to section.
I've installed ngProgress through bower. I have css and js in place.
In my app.js I have this:
(function(app) {
app.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
}]);
app.run(function () {});
app.controller('AppController', ['$scope', function ($scope) {
}]);
}(angular.module("grinFood", [
'grinFood.home',
'grinFood.about',
'grinFood.menu',
'grinFood.catering',
'grinFood.takeithome',
'grinFood.contact',
'templates-app',
'templates-common',
'ui.router.state',
'ui.router',
'ngProgress',
])));
Then for example my catering.js looks like this:
(function(app) {
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('catering', {
url: '/catering',
views: {
"main": {
controller: 'CateringController',
templateUrl: 'catering/catering.tpl.html'
}
},
data:{ pageTitle: 'Catering' }
});
}]);
app.controller('CateringController', ['$scope', function ($scope, ngProgress) {
var init = function() {
// A definitive place to put everything that needs to run when the controller starts. Avoid
// writing any code outside of this function that executes immediately.
ngProgress.start();
};
init();
}]);
}(angular.module("grinFood.catering", [
'ui.router'
])));
That is when I get TypeError: Cannot read property 'start' of undefined
Also tried to put the ngprogress in the controller in app.js but I can't make it work.
You can watch the error here: http://ticketcomunicacion.com/grinfood/#/menu
Any help would be appreciate. Thanks
First off, ngbp looks like it's out of date. Try http://yeoman.io/ Secondly, I'm clueless why do you wrap app with a function? This is pointless, unless that you have a other library with a conflict.
Do you use minifiers? If yes try use one that is aware of anugarjs dependency framework. Basically, you need to specify your dependency correctly
['$scope', function ($scope, ngProgress)
change to
function ($scope, ngProgress)
or
['$scope', 'ngProgress', function ($scope, ngProgress)
You are not injecting ngProgress into the controller properly.
Instead of this:
app.controller('CateringController', ['$scope', function ($scope, ngProgress) {
You need to do this:
app.controller('CateringController', ['$scope', 'ngProgress', function ($scope, ngProgress) {
Note, a while back I switched to using ng-annotate, it's a very nice way to avoid these errors. I actually use ng-annotate-rails. These will help you avoid these types of mistakes in the future and clean up your code a bit. I highly recommend either one!