angularJS module bootstrap issues angular-appinsights - angularjs

Hoping someone can help me out here... We are new to angularJS but have committed to using it on an upcoming project. One of the things we want to get in place from the start is app feature usage monitoring and we are planning to use Microsoft's Application Insights to do that. I was very happy to discover that there is an angularJS module already built for working with app insights recommended on Microsoft's getting started page for App Insights angular-appinsights. Unfortunately we are having a very difficult time bootstrapping this module.
Pretty sure we are the problem here, I feel that if we knew a little more about angularJS we could figure this out but since we are just cutting our teeth on it I am turning to SO for help!
So here is the portion of index.html where we are loading all of our scripts:
<!-- 3rd party libraries -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.min.js"></script>
<script src="scripts/angular-local-storage.min.js"></script>
<script src="scripts/loading-bar.min.js"></script>
<script src="scripts/angular-appinsights.js"></script>
<!-- Load app main script -->
<script src="app/app.js"></script>
Here is the relevant portion of app.js where everything is wired up:
var app = angular.module('MTCAPITester', ['ngRoute', 'LocalStorageModule', 'angular-loading-bar','angular-appinsights']);
app.config(['$routeProvider','insightsProvider',function ($routeProvider,insightsProvider) {
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "/app/views/home.html"
});
$routeProvider.when("/login", {
controller: "loginController",
templateUrl: "/app/views/login.html"
});
$routeProvider.otherwise({ redirectTo: "/home" });
insightsProvider.start('our app insights key here');}]);
And here is the app insights javascript that you are supposed to put in the head tag of index.html:
<script type="text/javascript">
var appInsights = window.appInsights || function (config) {
function s(config) { t[config] = function () { var i = arguments; t.queue.push(function () { t[config].apply(t, i) }) } } var t = { config: config }, r = document, f = window, e = "script", o = r.createElement(e), i, u; for (o.src = config.url || "//az416426.vo.msecnd.net/scripts/a/ai.0.js", r.getElementsByTagName(e)[0].parentNode.appendChild(o), t.cookie = r.cookie, t.queue = [], i = ["Event", "Exception", "Metric", "PageView", "Trace"]; i.length;) s("track" + i.pop()); return config.disableExceptionTracking || (i = "onerror", s("_" + i), u = f[i], f[i] = function (config, r, f, e, o) { var s = u && u(config, r, f, e, o); return s !== !0 && t["_" + i](config, r, f, e, o), s }), t
};
window.appInsights = appInsights;
</script>
Unfortunately we consistently get the ugly angular modulerr which I assume is telling me it can't bootstrap this module b/c if I remove the code related to this module everything works fine.
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.2.16/$injector/modulerr?p0=MTCAPITester&p1=Er…gleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.16%2Fangular.min.js%3A32%3A445)
Can anyone help me understand what we are missing here? I don't quite understand where the reference to insightsProvider is coming into play as I don't have that defined anywhere and I don't see it defined in his library either.
Any help with this would be greatly appreciated, this seems pretty straight forward but I am just not comfortable enough with angularJS at this point to understand where/why this is failing...

Another issue I've found with 'angular-appinsights.js' is, If you are using the ngRoute directive in your angular application for routing, then you should be okay. But if you are using ui.router for routing/states then 'angular-appinsights.js' will not work correctly and will throw an error. I found a fix for this here Angular-AppInsights – Unknown Provider – FIX, and its quite simple. In the .run function of the angular-appinsights.js module, you will find $route is being injected. If you remove $route from being injected into that function, angular-appinsights will work.

Turns out that the MS provided JS that they instruct you to put in the head tag of index.html was the source of the problem. Sperr speculated that maybe it was run before angular was loading. Solution to the problem was to pull that js out of the head tag and put it in its own .js file, then include it below the reference to angular-appinsights.js. With that change, everything is working great.

Related

AngularJS error [$injector:unpr] Unknown provider: in IE11

I couldn't find help in Google or here either. I'm new to Angular and I'm facing this error only in IE11 and below.
The error I'm getting is this:
My IE is in Portuguese so the translate of the first error is: it's not possible to get property of "getAttribute" of undefined or null
this is my app.config.js file
// Checking if an optional module is registered.
// If it's not, register an empty one to prevent errors.
(function(optDeps){
optDeps.forEach(function(dep){
try{
angular.module(dep);
}catch(e){
angular.module(dep, []);
}
})
})(['ui.carousel', 'ui.mask', 'vAccordion', 'ngAnimate']);
angular
.module('poletto', [
// Third party
'smoothScroll',
'ui.carousel',
'ui.mask',
'vAccordion',
'ngAnimate',
// Components
'poletto.components',
// Controllers
'poletto.controllers',
// Directives
'poletto.directives',
// Factories
'poletto.factories',
// Filters
'poletto.filters',
// Services
'poletto.services'
])
.constant('CONSTANTS', {
BASE_URL: document.currentScript.getAttribute('data-base-url')
})
.config(function($httpProvider){
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
})
.config(function($locationProvider){
if(window.history.pushState){
$locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
}
})
// Extending JQLite with a function that find nodes by className
.run(function(){
angular.element.prototype.findBySelector = function(selector){
var matches = [];
for(key in this){
// Pushing only HTMLElement's
if(this[key].nodeType){
// NodeList to array
var results = Array.prototype.slice.call(this[key].querySelectorAll(selector));
matches.push.apply(matches, results);
}
}
return angular.element(matches);
};
})
I've searched google and tried some solutions such as:
add <meta http-equiv="X-UA-Compatible" content="IE=11" />
wrap all my declarations in:
(function (angular) {
"use strict";
//code
}(window.angular));
add this in html tag:
<html lang="pt-br" xmlns:ng="http://angularjs.org">
Also I couldn't find any angular polyfills neither src/ folder, which I saw in a similar question with angular 2.
I don't know which file I should put here, so if you need some more info, you can ask me and I update the question.
Unfortunately document.currentScript is not supported on IE and can't be polyfilled so it can't done that way. Perhaps, you can embed the base url somewhere else or maybe add an id to your script and retrieve it in old school javascript.
<script id="main" data-base-url="https://my-api.com"></script>
And then retrieve it like this:
var currentScript = document.getElementById('main');
In your CONSTANTS provider you can do something like this:
.constant('CONSTANTS', {
BASE_URL: document.getElementById('main').getAttribute('data-base-url')
})
The problem stems from using document.currentScript, which isn't supported in IE 11 and apparently can't be polyfilled (easily at least). So you'll have to find a different way to declare your BASE_URL constant.

Angular Initialization errors in app.js

So I am trying to jump on the Angular bandwagon, and I have been tasked with building an SPA, for which I have selected AngularJS with ASP.Net MVC Web API (I am a .Net developer). As a fan of strongly typed languages, I have avoided javascript whenever possible throughout my career, but frameworks like AngularJS and the other libraries & plugins in recent years have made it impossible to ignore. So here I am, asking for some guidance.
I have watched the tutorials, done the sample code projects and done some learning on PluralSight, and I have things working, at least from a foundational perspective. I have a rich background in MVVM and MVC, so SOC is a big thing for me. I like the MVC type of structure that Angular provides, which is largely why I went this route in the first place.
Now let me get to my issue(s). I am initializing my module (currently) in my master page (_Layout.cshtml), which I did while tweaking and experimenting, for the sake of simplicity.
<script>
angular.module('xcmApp', ['ngRoute', 'ngResource'])
.config(function ($routeProvider) {
$routeProvider
.when('/',
{
controller: 'companiesController',
templateUrl: 'views/companylist.html'
})
.when('/Reports',
{
controller: 'reportsController',
templateUrl: 'views/reportlist.html'
})
.otherwise({ redirectTo: '/' })
})
.factory('companiesFactory', ['$resource',
function ($resource) {
return $resource('/api/companies', {}, {
query: { method: 'GET', params: {}, isArray: true }
});
}
])
.controller('companiesController', function ($scope, companiesFactory) {
$scope.Companies = companiesFactory.query();
});
</script>
But now that I am ready to move on to deeper concepts, I want to break my scripts out into their appropriate files. Namely, app.js and associated controllers/factories/services etc. However when I move that script into app.js and reference it in _Layout.cshtml, it errors:
<script src="~/app.js"></script>
Error: [$injector:unpr] Unknown provider: a
Now there's no point in continuing to break out into controller files etc. when I can't even get the app.js to work right, so here I am stuck. I know there are some brilliant AngularJS devs on here that probably know what I'm missing before even reading this far, and I am grateful for your assistance.
Anyone who can highlight my oversight will be a superstar for me today. Thanks in advance!
EDIT:
Here is my Stack Trace:
0x800a139e - JavaScript runtime error: [$injector:modulerr] Failed to instantiate module xcmApp due to:
Error: [$injector:unpr] Unknown provider: a
http://errors.angularjs.org/1.3.15/$injector/unpr?p0=a
at Anonymous function (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4015:13)
at getService (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4162:11)
at invoke (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4191:9)
at runInvokeQueue (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4109:11)
at Anonymous function (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4118:11)
at forEach (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:323:11)
at loadModules (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4099:5)
at createInjector (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4025:3)
at doBootstrap (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:1452:5)
at bootstrap (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:1473:5)
http://errors.angularjs.org/1.3.15/$injector/modulerr?p0=xcmApp&p1=Error%3A%20%5B%24injector%3Aunpr%5D%20Unknown%20provider%3A%20a%0Ahttp%3A%2F%2Ferrors.angularjs.org%2F1.3.15%2F%24injector%2Funpr%3Fp0%3Da%0A%20%20%20at%20Anonymous%20function%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4015%3A13)%0A%20%20%20at%20getService%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4162%3A11)%0A%20%20%20at%20invoke%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4191%3A9)%0A%20%20%20at%20runInvokeQueue%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4109%3A11)%0A%20%20%20at%20Anonymous%20function%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4118%3A11)%0A%20%20%20at%20forEach%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A323%3A11)%0A%20%20%20at%20loadModules%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4099%3A5)%0A%20%20%20at%20createInjector%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4025%3A3)%0A%20%20%20at%20doBootstrap%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A1452%3A5)%0A%20%20%20at%20bootstrap%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A1473%3A5)
REMINDER:
My problem is not that it doesn't work, it DOES WORK. It just STOPS working when I take the Javascript out of my HTML page and place it into a referenced app.js file.
Go back to the documentation. You are using a bad way of defining your application. Try:
var MyApp = angular.module( 'MyApp', ['ngRoute' , 'ngSanitize']) ;
and then use MyApp to add controllers, filters, etc.
EDIT:
BTW, it is a good practice to write the Javascripts in separate files for SPA (you are not writing a small project I guess).
It looks like you are missing a few declaration pieces related to Dependency Injection in your controller definition.
Before I post the specific code and fixes, I want to mention a useful troubleshooting tool for Dependency Injection issues. Angular has a built in directive ng-strict-di. This directive is a companion to ng-app. From the ng-app documentation:
if this attribute is present on the app element, the injector will be created in "strict-di" mode. This means that the application will fail to invoke functions which do not use explicit function annotation (and are thus unsuitable for minification), as described in the Dependency Injection guide, and useful debugging info will assist in tracking down the root of these bugs.
Now, to the code in your post:
Your controller is not using explicit function annotation. In explicit function annotation, you pass a string array of dependencies, followed by the function. This ensures that even if minification were to rename the function parameters, Angular can still identify which dependency to supply to the function. You have used explicit annotation in parts of your code, but it is missing from your controller definition.
This is classically easy to identify, with Error: [$injector:unpr] Unknown provider: a, even though you never defined a provider named a. ng-strict-di would flag this controller code.
Here is the current code, and the proposed fix.
Instead of:
.controller('companiesController', function ($scope, companiesFactory) {
Try:
.controller('companiesController', ['$scope', 'companiesFactory', function ($scope, companiesFactory) {
I don't have an ASP.net background, but I think that souldn't matter to answer your Angular question.
First declare your modules like this:
angular.module('myModule', []);
and get them im oder files like this:
angular.module('myModule').controller/foactory/....
So your code should look something like this:
//xcmApp.module.js
angular.module('xcmApp', ['ngRoute', 'ngResource']);
//xcmApp.config.js
angular.module('xcmApp').config(function ($routeProvider) {
$routeProvider
.when('/',
{
controller: 'companiesController',
templateUrl: 'views/companylist.html'
})
.when('/Reports',
{
controller: 'reportsController',
templateUrl: 'views/reportlist.html'
})
.otherwise({redirectTo: '/'})
});
//xcmApp.factory.js
angular.module('xcmApp').factory('companiesFactory', ['$resource',
function ($resource) {
return $resource('/api/companies', {}, {
query: {method: 'GET', params: {}, isArray: true}
});
}
]);
//xcmApp.controller.js
angular.module('xcmApp').controller('companiesController', function ($scope, companiesFactory) {
$scope.Companies = companiesFactory.query();
});
EDIT:
Regarding the error, keep in mind that your dependencies must be in the rigth order.
So your index.html (assuming you use don't use a script loader yet) should look like this:
<script src="/*path to angular*/"></script>
<script src="/*path to ngRoute*/"></script>
<script src="/*path to ngResource*/"></script>
<script src="/*path to xcmApp.module.js*/"></script> //setting your app module must come first
<script src="/*path to xcmApp.config.js*/"></script>
<script src="/*path to xcmApp.factory.js*/"></script> //must come before the controller in your case
<script src="/*path to xcmApp.controller.js*/"></script>

No Permission error using Firebase

I am trying to add Firebase for the first time to an ionic application. I have set up my project and referenced the javascript files however when I run the application I see the error 'Error: Permission Denied'
I have not yet set up authentication in my app but, if I am understanding things properly I shouldn't need to do this while I am just testing.
My index.html contains the following:
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.2.0/angularfire.min.js"></script>
While the app.js has the following lines:
angular.module('starter', ['ionic', 'firebase'])
.factory("Items", function($firebaseArray) {
var itemsRef = new Firebase("https://todo-83e58.firebaseio.com/items");
return $firebaseArray(itemsRef);
})
.controller('ListCtrl', function($scope, $ionicListDelegate, Items) {
$scope.items = Items;
$scope.addItem = function () {
var name = prompt("what do you need to buy?");
if (name) {
$scope.items.$add({"name": name});
}
};
I would be grateful for any pointers on how to get the basics right as I have tried following the information on the Firebase site and I seem to have it all set up correctly. Am I misunderstanding the authentication or shouldI be able to write to the database without setting this up first ?
It sounds that your Security & Rules isn't giving you access to items. Please make sure to spend some time reading the S&R documentation.
If you are only testing the application and don't want to care about it now just set it to full read and write.
On the new console go to Database > Rules.
{
"rules": {
".read": true,
".write": true
}
}

Angular JS Problemsss [duplicate]

I am writing a sample application using angularjs. i got an error mentioned below on chrome browser.
Error is
Error: [ng:areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=not%20a%20function%2C%20got%20undefined
Which renders as
Argument 'ContactController' is not a function, got undefined
Code
<!DOCTYPE html>
<html ng-app>
<head>
<script src="../angular.min.js"></script>
<script type="text/javascript">
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
</script>
</head>
<body>
<h1> modules sample </h1>
<div ng-controller="ContactController">
Email:<input type="text" ng-model="newcontact">
<button ng-click="add()">Add</button>
<h2> Contacts </h2>
<ul>
<li ng-repeat="contact in contacts"> {{contact}} </li>
</ul>
</div>
</body>
</html>
With Angular 1.3+ you can no longer use global controller declaration on the global scope (Without explicit registration). You would need to register the controller using module.controller syntax.
Example:-
angular.module('app', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
or
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);
It is a breaking change but it can be turned off to use globals by using allowGlobals.
Example:-
angular.module('app')
.config(['$controllerProvider', function($controllerProvider) {
$controllerProvider.allowGlobals();
}]);
Here is the comment from Angular source:-
check if a controller with given name is registered via $controllerProvider
check if evaluating the string on the current scope returns a constructor
if $controllerProvider#allowGlobals, check window[constructor] on the global window object (not recommended)
.....
expression = controllers.hasOwnProperty(constructor)
? controllers[constructor]
: getter(locals.$scope, constructor, true) ||
(globals ? getter($window, constructor, true) : undefined);
Some additional checks:-
Do Make sure to put the appname in ng-app directive on your angular root element (eg:- html) as well. Example:- ng-app="myApp"
If everything is fine and you are still getting the issue do remember to make sure you have the right file included in the scripts.
You have not defined the same module twice in different places which results in any entities defined previously on the same module to be cleared out, Example angular.module('app',[]).controller(.. and again in another place angular.module('app',[]).service(.. (with both the scripts included of course) can cause the previously registered controller on the module app to be cleared out with the second recreation of module.
I got this problem because I had wrapped a controller-definition file in a closure:
(function() {
...stuff...
});
But I had forgotten to actually invoke that closure to execute that definition code and actually tell Javascript my controller existed. I.e., the above needs to be:
(function() {
...stuff...
})();
Note the () at the end.
I am a beginner with Angular and I did the basic mistake of not including the app name in the angular root element. So, changing the code from
<html data-ng-app>
to
<html data-ng-app="myApp">
worked for me. #PSL, has covered this already in his answer above.
I had this error because I didn't understand the difference between angular.module('myApp', []) and angular.module('myApp').
This creates the module 'myApp' and overwrites any existing module named 'myApp':
angular.module('myApp', [])
This retrieves an existing module 'myApp':
angular.module('myApp')
I had been overwriting my module in another file, using the first call above which created another module instead of retrieving as I expected.
More detail here: https://docs.angularjs.org/guide/module
I just migrate to angular 1.3.3 and I found that If I had multiple controllers in different files when app is override and I lost first declared containers.
I don't know if is a good practise, but maybe can be helpful for another one.
var app = app;
if(!app) {
app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);
I had this problem when I accidentally redeclared myApp:
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller1', ...);
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller2', ...);
After the redeclare, Controller1 stops working and raises the OP error.
Really great advise, except that the SAME error CAN occur simply by missing the critical script include on your root page
example:
page: index.html
np-app="saleApp"
Missing
<script src="./ordersController.js"></script>
When a Route is told what controller and view to serve up:
.when('/orders/:customerId', {
controller: 'OrdersController',
templateUrl: 'views/orders.html'
})
So essential the undefined controller issue CAN occur in this accidental mistake of not even referencing the controller!
This error might also occur when you have a large project with many modules.
Make sure that the app (module) used in you angular file is the same that you use in your template, in this example "thisApp".
app.js
angular
.module('thisApp', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
index.html
<html>
<body ng-app='thisApp' ng-controller='ContactController>
...
<script type="text/javascript" src="assets/js/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
If all else fails and you are using Gulp or something similar...just rerun it!
I wasted 30mins quadruple checking everything when all it needed was a swift kick in the pants.
If you're using routes (high probability) and your config has a reference to a controller in a module that's not declared as dependency then initialisation might fail too.
E.g assuming you've configured ngRoute for your app, like
angular.module('yourModule',['ngRoute'])
.config(function($routeProvider, $httpProvider) { ... });
Be careful in the block that declares the routes,
.when('/resourcePath', {
templateUrl: 'resource.html',
controller: 'secondModuleController' //lives in secondModule
});
Declare secondModule as a dependency after 'ngRoute' should resolve the issue. I know I had this problem.
I was getting this error because I was using an older version of angular that wasn't compatible with my code.
These errors occurred, in my case, preceeded by syntax errors at list.find() fuction; 'find' method of a list not recognized by IE11, so has to replace by Filter method, which works for both IE11 and chrome.
refer https://github.com/flrs/visavail/issues/19
This error, in my case, preceded by syntax error at find method of a list in IE11. so replaced find method by filter method as suggested https://github.com/flrs/visavail/issues/19
then above controller not defined error resolved.
I got the same error while following an old tutorial with (not old enough) AngularJS 1.4.3. By far the simplest solution is to edit angular.js source from
function $ControllerProvider() {
var controllers = {},
globals = false;
to
function $ControllerProvider() {
var controllers = {},
globals = true;
and just follow the tutorial as-is, and the deprecated global functions just work as controllers.

AngularJS $routeProvider injection fails in directive

I am currently trying to get in touch with AngularJS. Since I plan to build a rather complex web application I searched for an alternative to the ngView/$routeProvider combination to be found in the ng docs as I find them quite dissatisfying for a complex application with several navigation levels.
So what I tried is to write a custom directive called ngRoute that could be used like this:
<div ng-route="users">
<div ng-route=":id"></div>
<div ng-route></div><!-- default -->
</div>
What I currently have is the following directive definition:
angular.module('app').directive('ngRoute', function($routeProvider) {
var getRoute = function($el) {
var parts = [];
var $curEl = $el;
while($curEl.length > 0) {
parts.unshift($curEl.attr('ng-route'));
$curEl = $curEl.parent().closest('*[ng-route]');
}
return parts.join('/');
}
var directiveDef = {
link: function(scope, $el, iAttrs, controller) {
var route = getRoute($el);
// Register route observer dependant on calculated route...
}
};
return directiveDef;
});
Unfortunately, I get an error due to the DI of the $routeProvider which I need for the registration of the route observation:
Error: Unknown provider: appProvider <- app <- ngRouteDirective
Did I miss something here? Also, feel free to critisize my approach (maybe someone already found a better solution for my problem).
Yeah, I'm not too clear about the approach but shouldn't the dependancy injection be:
angular.module('app')
.directive('ngRoute',['$routeProvider, function($routeProvider) {
// etc,etc...
};
]);
I ended up using the router of the angular-ui project (http://github.com/angular-ui/ui-router)
I find it to be quite satsifying
Unfortunately, I still have no clue why my DI did not work properly
I just ran into this as well using Angular version 1.2.7 (latest as of posting date).
Jumping over to ui-router is tempting but I thought I would offer a work around (albeit a little hacky) that I have working and is stable.
First set up routes as usual, but add $routeProvider to your application:
app.config(function($routeProvider) {
$routeProvider.
when('/a/route/here', {action:"someAction"}).
otherwise({redirectTo:'index'});
app.routeProvider = $routeProvider;
});
Then in the directive add additional routes as needed using:
app.routeProvider.when(...);
Angular adds the new routes and processes them fine when you navigate to them.

Resources