I'm new to Angular so i'm still getting my head around how it works. I've stumbled into a problem however (quite early on...) and the below code is giving me "Uncaught Object" in the console and breaks Angular. The .config section is the culprit, if I remove it, the page loads fine. I'm not entirely sure how the error is being caused because to me, everything looks fine?
var app = angular.module('app', ['ngRoute'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/dashboard', {
templateUrl: '/app/views/admin.html',
controller: 'DashboardController'
})
.otherwise('/', {
redirectTo: '/'
})
$locationProvider.html5mode(true);
}])
.controller('DashboardController', ['$scope', function ($scope, Security) {
$scope.security = Security;
}])
I had the same error; if you activate Chrome to pause on exceptions, you'll be able to have more detailed error information
.otherwise takes only one parameter - an object which contains information on what needs to be done for routes that are not defined.
In your case, you seem to be passing a route to it in addition to an object.
Replace:
.otherwise('/', {
redirectTo: '/'
})
with
.otherwise({
redirectTo: '/dashboard'
});
Note that you need to redirect to a path that exists. '/' is a path that does not exist. '/dashboard' is a path that does, hence you redirect to it. Or, define a handler for '/' path
I'm posting my own solution, as several factors seem to be behind this issue and nobody has talked about this so far.
That is, try to write your code outside of $.ready();
<script>
$(function(){
// This leaves "Uncaught object" error in Chrome!
// var app = angular.module('testApp', ['ngRoute']);
});
// So get it out of $.ready()!!
var app = angular.module('testApp', ['ngRoute']);
</script>
In this instance it looks like the error has been caused by this:
$locationProvider.html5mode(true); <-- mode should be capital 'M'.
Be sure your angular.js is loaded before angular-route.js in your HTML file.
like:
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-route.js"></script>
I just ran into this, in my case it was due to using UI-Router and having a duplicated state name.
Related
I've done quick client-side routing with angular 1.4.4. In every tutorial I saw approach where you assign module to variable (usually: app) and perform different tasks on it, like below:
var app = angular.module('skeleton', [ngResource, ngRoute]);
app.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$routeProvider
.when('/', {
templateUrl: '/partials/main',
controller: 'MainController'
});
});
app.controller('MainController', function ($scope) {
$scope.test = 'Hi Angular';
});
In tutorial which I'm doing now I see completely different approach:
angular.module('skeleton', ['ngResource', 'ngRoute']);
angular.module('skeleton').config(function($routeProvider, $locationProvider){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$routeProvider
.when('/', { templateUrl: '/partials/main', controller: 'mainCtrl'});
});
angular.module('skeleton').controller('mainCtrl', function($scope){
$scope.test = "Hello Angular";
});
I assumed it's just preference, so i went with 'app' version as I find it more readable.
Unfortunately it causes angular to throw
ReferenceError: ngResource is not defined
Anyone know what is cause of this behaviour?
Which approach do you prefer?
You need to to inject dependency properly, pass ngResource and ngRoute within quotes, otherwise they are treated as variable hence you must be getting the error.
var app = angular.module('skeleton', ['ngResource', 'ngRoute']);
Firstly , The issue is not with assigning the module declaration to a variable 'app' and then using it. Both approaches work but it is better to declare without assigning it to a variable which avoids variable collisions which could lead to module overriding.
The issue in your code is the syntax. Please correct it as shown below :
var app = angular.module('skeleton', ['ngResource', 'ngRoute']);
dependency Annotation can also be done by assigning the array of dependencies to the '$inject' property or directly as the function properties .
Please refer to this angular guide for reference :
https://docs.angularjs.org/guide/di
I have followed the instructions from https://github.com/angular-ui/ui-router/wiki/URL-Routing
but cannot get this to work properly.
I have the following:
var application = angular.module('application', ['ui.router']);
application.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise("/test");
$stateProvider
.state('index', {
url: "/test/:param",
templateUrl: "App/Test.html",
controller: function ($scope, $stateParams) {
alert($stateParams.param);
}
});
$locationProvider.html5Mode(true);
});
Without the /:param this works as you would expect - i.e. the ui-view is correctly populated with Test.html. However, whenever I put the /:param in I get an error. The error is:
GET http://localhost:3880/test/App/Test.html 404 (Not Found)
App is the route of my angular stuff and Test.html should have a path of
http://localhost:3880/App/Test.html
which it does if not trying /:param. However, when trying /:param you can see that there is an extra /test/ in the path before /App.
Please someone help, as I would like to consume the parameter in the controller once it is correct.
You URL for this route should be like this : http://localhost:3880/test/app Where app is param.
Use absolute path for templateUrl. relative url wont work.
templateUrl: "/path/to/App/Test.html",
What's wrong with this AngularJS configuration code?
(function () {
var ip = 'x.x.x.x';
var app = angular.module('cmal', ['controllers', 'directives', 'services', 'ngRoute'])
.constant("baseUrl", "http://" + ip + ":303/angular")
.config( function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when('/', { templateUrl: "index.html"});
$routeProvider.when('/users', { templateUrl: "users.html"});
$routeProvider.otherwise({template: "Sorry, the page you are trying to reach doesn't exist."});
});
})();
EDIT: it's not the slash error. This still doesn't work for me and all i get in the console is "Uncaught object"
EDIT 2: Well i didn't realize you needed to import another js script for routing. But so now that I have done that, I get no error, but none of the routes work.
You are probably not including the separate angular-route script.
Take a look at this answer for more details.
This isn't really an answer, but an alternative solution...I used a separate routing framework.
UI-Router (a link to the egghead tutorial)
I'm very new to Angular and I'm currently building a few test/dummy apps to get my head around the way it works and become more-familiar with SPA's in Angular. However, I've stumbled into an issue when I start adding routes to my application and loading the content via ng-view
$locationProvider doesn't seem to be working correctly because if I go to localhost/sdfsdf then I get cannot GET /sdfsdf when in reality the page should be redirecting to /cocktails.
routes.js
var cocktailApp = angular.module('cocktailApp', ['ngRoute', 'cocktailControllers']);
cocktailApp.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/cocktails', {
templateUrl: '/partials/cocktail-list.html',
controller: 'cocktailsController'
})
.otherwise({
redirectTo: '/cocktails'
});
$locationProvider.html5mode(true);
}]);
Angular only recognizes anchor URL syntax for URLs pasted directly on the browser. So you have to you try http://localhost/#/sdfsdf instead to make your routing work. Please note that anchor syntax /# was added in previous URL.
I have my backend web framework loading my AngularJS app with following URL
http://localhost/New/Alpha/App
I also have it set up so that anything after App will still load the same thing
http://localhost/New/Alpha/App/home
http://localhost/New/Alpha/App/settings
...
I'm trying to make my AngularJS app to work in the way that it would pick up the bit of URL after App and load a controller/template accordingly. I have a problem with routing in my AngularJS app though
var main = angular.module("main", ["ui.bootstrap", "ngRoute"]);
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: "fail"
});
$locationProvider.html5Mode(true);
});
main.controller("mainController", function($scope) {
console.log("home")
});
If I try this URL
http://localhost/New/Alpha/App/home
it changes the URL to
http://localhost/fail
instead of leaving the URL as it is and loading the template/controller. If however I change the config and give it a full relative URL it does work as supposed to
.when("/New/Alpha/App/home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
My problem is, that the part of URL before App - /New/Alpha cannot be hardcoded in. It could be /New/Beta, /New/Gamma, etc.
Is what I want to do possible at all without hardcoding the full relative URL match?
UPDATE Sorry, forgot to mention that the number of URL segments before App can change, as in it could be /New/Beta/App and it also could be /New/Another/Beta/App. I don't suppose something like */App or /New/*/App is possible instead of /New/:placeholder/App?
Will this work for you?
var main = angular.module("main", ["ui.bootstrap", "ngRoute"]);
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("/New/:greek/App/home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: "fail"
});
$locationProvider.html5Mode(true);
});
main.controller("mainController", function($scope) {
console.log("home")
});
You could then retrieve the greek with $routeParams.greek from within your controller.
The general solution to this problem is to have the server pass the app URL to your client-side code. In other words, use server-side code to dynamically write the equivalent of the following on the page:
var appUrl = '/New/Alpha/App';
Then setting up the route provider becomes:
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when(appUrl + "/home", {
templateUrl: "/assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: appUrl + "/fail"
});
$locationProvider.html5Mode(true);
});
That way the knowledge of the application base URL lives in one place — server-side (which makes sense as only the server is in a position to truly know, if you think about it).
In your specific case, if the application base URL is implicit in the URL structure, you could calculate the following client-side:
var appUrl = window.location.pathname.match(/^\/New\/.*\/App/);
Needs work, but you get the idea. Then you can set up the route provider exactly as above.