I have a very simple application that does nothing really other than display two different views depending on user selection. This application is a stepping stone to learning how routes work in AngularJS.
My issue is this.
The application when run in the browser navigates to the index view with no issues. This is because the index view does not reference a controller. However the user view does reference (require) a controller. This causes an issue where the exception thrown is Arguement 'XCtrl' is not a function, got undefined.
My main index is:
<html>
<head><title></title></head>
<body>
<div ng-view></div>
</body>
</html>
My main app.js is:
angular.module('app.controllers', []);
var controllers = angular.module('app.controllers', []);
angular.module('app', ['app.controllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/index.html'
})
$routeProvider.when('/users', {
templateUrl: 'views/users.html',
controller: 'UserCtrl'
}).
otherwise({ redirectTo: '/' });
}]);
My controller is:
appControllers.controller('UserCtrl', ['$scope', function ($scope) {
$scope.users = {
user: {name: "Ian", age: 30 },
user: {name: "Paul", age: 37 }
};
}]);
user.html
<div ng-repeat="user in users">{{user.name}} {{ user.age }}</div>
index.html
<h1>index</h1>
can anybody see where I am going wrong. Any help would be great
EDIT:
Here s the stack trace from the browser, if this helps any
Error: Argument 'UserCtrl' is not a function, got undefined
at Error ()
at bb (http://www.testapp.com/js/angular/angular.min.js:17:68)
at ra (http://www.testapp.com/js/angular/angular.min.js:17:176)
at http://www.testapp.com/js/angular/angular.min.js:53:60
at k (http://www.testapp.com/js/angular/angular.min.js:151:401)
at Object.e.$broadcast (http://www.testapp.com/js/angular/angular.min.js:90:517)
at http://www.testapp.com/js/angular/angular.min.js:83:6
at h (http://www.testapp.com/js/angular/angular.min.js:78:207)
at h (http://www.testapp.com/js/angular/angular.min.js:78:207)
at http://www.testapp.com/js/angular/angular.min.js:78:440
Also:
www.testapp.com is a locally hosted server with no external access, just in case someone tries it and can not access.
After see a related question I noticed that I had not added the UserCtrl.js to my main index.html. After adding this it worked. However, I believe there is a way to add controllers, directives, services and filters dynamically. If someone knows how to do this it would be very helpful.
Delete the brackets during assignments
angular.module('app.controllers', []);
var controllers = angular.module('app.controllers');
Or simpler do just htis:
var controllers = angular.module('app.controllers', []);
If you put the brackets you'll have two modules ...
Related
I don't understand why I can't get this to work.
I'll share the relevant code, let me know if you need to see more stuff.
Index.html
<div class="col-md-3">Liberals</div>
app.js
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider.
when("/liberals", {
templateUrl: "partials/liberals.html"
, controller: "LiberalsController"
});
});
app.controller('LiberalsController', function ($scope, $http) {
var url = "workingURL"; /// changed function to a simple string message to test
$scope.message = "Hello Liberals";
});
(partial view) liberals.html
<h1>Hello</h1>
{{message}}
PS: I'm not working on a political hate website for or against liberals!
As of AngularJS 1.6, the default value of the hashPrefix has been changed to !.
There's two ways to get your routing to work with AngularJS 1.6+:
Add the hashprefix (!) to your href's:
Liberals
Change (remove) the hashPrefix value using $locationProvider:
$locationProvider.hashPrefix('');
I've created a working plunkr in which I used the second approach:
https://plnkr.co/edit/oTB6OMNNe8kF5Drl75Wn?p=preview
The commit regarding this breaking change can be found here
I am using the Angular UI Router as my router. I have a $state defined as such:
$stateProvider.state('mypage', {
url:'/',
views: {
'content': {
templateUrl: 'folder/mypage.template.html',
controller: 'MyPageController'
}
}
})
I can go to MyPageController and do the following:
$rootScope.test = "hello!";
And then go to folder/mypage.template.html and put the following:
<div id="example">
{{test}}
</div>
hello! will show up in the rendered web page. However, if I instead do the following in MyPageController:
$scope.test = "hello!";
Nothing will show up in the template. This is very confusing to me, as I know that MyPageController is made available to the state (as I can add something to $rootScope and display it), but the $scope is not available. Does anyone have an idea as to what might be going on? Thank you :)
EDIT1:
MyPageController is part of a module, let's say myModule, that is imported into a top-level module. For example, it looks something like this:
angular.module('topLevelModule', [
'myModule'
]).config( ... $stateProvider stuff ... ).run( ... setup stuff ... )
angular.module('myModule')
.controller('MyPageController', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.test = "hello!";
}]);
EDIT2 (problem solved):
I had followed a tutorial that used the following pattern with multiple states in the UI-Router:
$stateProvider
.state('mainpage', {
url: '/',
views: {
'content': {
templateUrl: 'folder/mainpage.template.html',
controller: 'MainPageController' <-- POINT OF INTEREST 1
}
}
})
.state('mypage', {
url: 'my-page',
controller: 'MyPageController', <-- POINT OF INTEREST 2
views: {
'content#': {
templateUrl: 'folder/mypage.template.html',
<-- POINT OF INTEREST 3
}
}
})
}])
However, the problem lies in this formatting. This is just a heads up for anyone using the UI-Router who happened to follow the same tutorial as I did (I can't find the link), that POINT OF INTEREST 2 needs to be moved to POINT OF INTEREST 3 for the controller to properly be assigned upon state change -- syntax error. There were more complexities to why things were happening (due to my debugging approach) that were causing any inconsistencies you see above, but I won't include them here. Thanks everyone for their time. :)
var test = angular.module('test', []);
test.run(function() {
});
test.config(function() {
// your state for binding html with controller
});
test.controller('MyPageController ', function($scope) {
$scope.test = "hello!";
});
And then in HTML
<div id="example">
{{test}}
</div>
I am stuck in calling json text inside the ng-view. In normal HTML {{profile.experience}} this works perfect fine. fetching the data from json.
But since I have add the ng-view {{profile.experience}} is unable to fetch the data from json.
<div class="profile-snapshot">
<ul>
<li><span>Experience:</span><p> {{profile.experience}}</p></li>
<li><span>Education:</span><p> {{profile.education}}</p></li>
<li><span>Designation:</span><p>{{profile.designation}}</p></li>
<li><span>Age:</span><p>32</p></li>
<li><span>City:</span><p>Thane</p></li>
</ul>
</div>
This what my json look like
{
"experience": "Experience 8 Years asda s",
"education": "MBA, B.COM",
"designation": "UX Designer, Front End Developer"
}
this is what my angularjs code looks like
var accord = angular.module('accord', []);
var profileLoad = angular.module('profileLoad',[]);
var app2 = angular.module('main-app', ['accord','profileLoad','ngRoute']);
profileLoad.controller('profileCntrl', function($scope, $http){
'use strict';
$http.get('candidateProfile.json').success(function(data) {
$scope.profile = data;
});
});
app2.config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'profile.html',
controller: 'StudentController'
})
.when('/viewStudents', {
templateUrl: 'profile-edit.html',
controller: 'StudentController'
})
.otherwise({
redirectTo: '/home'
});
});
can anyone please help me in fetching the json data inside ng-view?
Unless I'm missing something, I think
profileLoad.controller('profileCntrl', function($scope, $http){ ... }
should be
profileLoad.controller('StudentController', function($scope, $http){ ... }
You're retrieving the data in a controller that's not mapped to a template in $routeProvider.
Also, you should put your $http.get in a service and inject that service into your controller. Keep your concerns separated and your controllers lean.
Since I was already applying the controller. Only thing I needed to do is remove the controller: 'StudentController'.
That solved the problem for me.
I really appreciate the quick reply from the members here.
Cheers guys
I have the following URL:
http://myUrl.com/#/chooseStyle?imgUpload=6_1405794123.jpg
I want to read the imgUpload value in the query string - I'm trying:
alert($location.search().imgUpload);
But nothing alerts, not even a blank alert - but console reads:
$location is not defined
I need this value to add into a controller to pull back data, and also to carry into the view itself as part of a ng-src
Is there anything I'm doing wrong? this is my app config:
capApp.config(function($locationProvider, $routeProvider) {
$locationProvider.html5Mode(false);
$routeProvider
// route for the home page
.when('/', {
templateUrl : '/views/home.html',
controller : 'mainController'
})
// route for the caption it page
.when('/capIt', {
templateUrl : '/views/capIt.html',
controller : 'mainController'
});
}):
This is the view:
<div class="container text-center">
<h1 class="whiteTextShadow text-center top70">Choose your photo</h1>
</div>
<script>
alert($location.search().imgUpload);
</script>
Main controller:
capApp.controller('mainController', function($scope) {
$scope.message = 'Whoop it works!';
});
My end goal is that I can find a solution to capturing and re-using data from the query string.
I will also mention, this is only my first week in Angular, loving it so far! A lot to learn...
<script>
alert($location.search().imgUpload);
</script>
You're making two mistakes here:
executing code while the page is loading, and the angular application is thus not started yet
assuming $location is a global variable. It's not. It's an angular service that must be injected into your controller (or any other angular component). This should cause an exception to be thrown and displayed in your console. Leave your console open always, and don't ignore exception being thrown.
You should not do this
<script>
alert($location.search().imgUpload);
</script>
// you need to inject the module $location
//(either in service, or controller or wherever you want to use it)
// if you want to use their APIs
capApp.controller('mainController', function($scope, $location) {
$scope.message = 'Whoop it works!';
//use API of $location
alert($location.search().imgUpload);
});
I have a really simple Angular app that I've distilled to the following:
var napp = angular.module('Napp',['ngResource']);
var CompanyCtrl = function($scope, $routeParams, $location, $resource) {
console.log($routeParams);
};
napp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/company/edit/:id',
{templateUrl: '/partials/edit', controller: 'CompanyCtrl'}
);
}]);
and the HTML:
<div ng-controller="CompanyCtrl"></div>
When I log $routeParams, it comes up blank. When I use .otherwise(), it will load whatever I've specified there. Any idea what I'm missing?
You have a couple of errors:
You've specified the controller in two places, both in the view (<div ng-controller="CompanyCtrl"></div>) and in $routeProvider (.when('/company/edit/:id', {templateUrl: '/partials/edit', controller: 'CompanyCtrl'}). I'd remove the one in the view.
You have to register the controller in the module when specifying it in the $routeProvider (you should really do this anyway, it's better to avoid global controllers). Do napp.controller('CompanyCtrl', function ... instead of var CompanyCtrl = function ....
You need to specify a ng-view when you're using the $route service (not sure if you're doing this or not)
The new code:
var napp = angular.module('Napp', ['ngResource']);
napp.controller('CompanyCtrl', function ($scope, $routeParams, $location, $resource) {
console.log($routeParams);
});
napp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/company/edit/:id',
{templateUrl: '/partials/edit', controller: 'CompanyCtrl'}
);
}]);
The template (/parials/edit)
<div> ... </div>
And the app (index.html or something)
... <body> <div ng-view></div> </body>
I've created a working plunker example: http://plnkr.co/edit/PQXke2d1IEJfh2BKNE23?p=preview
First of all try this with
$locationProvider.html5Mode(true);
That should fix your starting code. Then adjust your code to support non-pushState browsers.
Hope this helps!
Not sure if this helps, but I just came across this issue myself, and found that I couldn't log the route params until I had something bound to them.
So,
Router:
var myApp = angular.module('myApp', []);
myApp.config(function($routeProvider){
$routeProvider.when('/projects/:id',
{templateUrl: '/views/projects/show.html', controller: 'ProjectCtrl'}
);
});
Controller:
myApp.controller('ProjectCtrl', function($scope, $routeParams){
$scope.id = $routeParams.id;
console.log('test');
});
View:
<h1>{{ id }}</h1>
When I removed the '{{id}}' from the view, nothing was logged and $routeParams was empty, at least at the time of the controller's instantiation. As some of the answers above have pointed to, the route params are passed in asynchronously, so a controller with no bindings to that property won't execute. So, not sure exactly what you've distilled your snippet down from, but hope this helps!
This may happen (not in the OP's case) if you're using ui-router instead of ngRoute.
If that's the case, use $stateParams instead of $routeParams.
https://stackoverflow.com/a/26946824/995229
Of course it will be blank. RouteParams is loaded asynchronously so you need to wait for it to get the params. Put this in your controller:
$scope.$on('$routeChangeSuccess', function() {
console.log($routeParams);
});
It works for me http://plunker.co/edit/ziLG1cZg8D8cYoiDcWRg?p=preview
But you have some errors in your code:
Your don't seem to have a ngView in your code. The $routeProvider uses the ngView to know where it should insert the template's content. So you need it somewhere in your page.
You're specifying your CompanyCtrl in two places. You should specify it either in the $routeProvider, or in you template using ng-controller. I like specifying it in the template, but that's just personal preference.
Although not an error, you're specifying your CompanyCtrl in the global scope, instead of registering it on your Napp module using Napp.controller(name, fn).
Hope this helps!
You can always go on #angularjs irc channel on freenode: there's always active people ready to help
Could it be that your templateUrl points to an invalid template?
When you change the templateUrl to an unexisting file, you will notice that the $routeParams will no longer be populated (because AngularJS detects an error when resolving the template).
I have created a working plnkr with your code for your convenience that you can just copy and paste to get your application working:
http://plnkr.co/edit/Yabp4c9zmDGQsUOa2epZ?p=preview
As soon as you click the link in the example, you will see the router in action.
Hope that helps!