I have a project where homeapp.js contains the angular.module dependencies:
var HomeApp = angular.module('HomeApp', [
'ngRoute',
'ngCookies',
'HomeControllers',
'metadataControllers',
'MyControllers',
'ScheduleControllers'
]);
HomeApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/schedules', {
templateUrl: 'pages/list_schedule.html',
controller: 'ScheduleControllers'
});
and in a ScheduleController.js, I have:
angular.module('ScheduleControllers', []).controller('PhoneListCrl', function($scope) {
$scope.phones = [
{'name': 'Nexus S',
'snippet': 'Fast just got faster with Nexus S.'},
{'name': 'Motorola XOOM with Wi-Fi',
'snippet': 'The Next, Next Generation tablet.'},
{'name': 'MOTOROLA XOOM',
'snippet': 'The Next, Next Generation tablet.'}
];
});
this is basically the code snippet from the angular tutorial.
In the index.html, I have:
<html lang="en-CA" ng-app="HomeApp">
...
<li id="id_schedule_list" class="header_list">List Schedule</li>
...
which then directs to this the schedules.html with only the follow codes:
<div>
<div ng-controller="PhoneListCrl">
<p>{{phones}}</p>
</div>
</div>
However when the html is opened from browser, it shows {{phones}} straight, without being able to show the full json object. The console says
https://docs.angularjs.org/error/ng/areq?p0=ScheduleControllers&p1=not%20a 1.#QNAN0unction%2C%20got%20undefined
Which doesn't really make sense to me, but I guess it is saying ScheduleControllers is undefined.
EDIT:
In angluar's tutorial, the app.js says:
var phonecatApp = angular.module('phonecatApp', [
'ngRoute',
'phonecatAnimations',
'phonecatControllers',
'phonecatFilters',
'phonecatServices'
]);
and then in controllers.js, it has:
var phonecatControllers = angular.module('phonecatControllers', []);
phonecatControllers.controller('PhoneListCtrl', ['$scope', 'Phone',
function($scope, Phone) {
$scope.phones = Phone.query();
$scope.orderProp = 'age';
}]);
Looks like I am almost doing exactly what the tutorial does, but why it doesn't work for me?
The problem is actually with the route. You are using the module's name for the controller instead of the actual controller name.
Where you have controller: 'ScheduleControllers', you instead need controller: 'PhoneListCtrl'. Additionally, the code you pasted has a typo in the controller definition. You need a t in PhoneListCtrl in
angular.module('ScheduleControllers', []).controller('PhoneListCtrl', function($scope) `
EDIT
In the following code, you are telling angular which controller to load when you access the /schedules route. Right now, it is pointing to 'ScheduleControllers', which is a module, not a controller. Change it to match the second block and you should be good to go.
HomeApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/schedules', {
templateUrl: 'pages/list_schedule.html',
controller: 'ScheduleControllers'
});
HomeApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/schedules', {
templateUrl: 'pages/list_schedule.html',
controller: 'PhoneListCtrl'
});
See https://docs.angularjs.org/tutorial/step_07 for reference.
You're attaching your controller to another Angular module:
// This line creates a new module named "ScheduleControllers"
// And attaches the "PhoneListCrl" to it.
angular.module('ScheduleControllers', []).controller('PhoneListCrl', function() { ... });
If you want it to be visible to your HomeApp then attach it to that module:
// You need to attach "PhoneListCrl" to your original module.
angular.module('HomeApp').controller('PhoneListCrl', function() { ... });
the controller: 'ScheduleControllers' is name of module and not controller, hence the issue
Related
I'm building an application in Rails and I'm using Angular for part of the front end, generating views based on data provided in a json file. I've been following this tutorial, but I can't seem to get my controller to run and I have no idea why. Can anyone help me out?
Sample link: http://localhost:3000/events/events1
events.coffee.erb
app = angular.module('EventsApp', ['ui.router', 'templates'])
app.config [
'$stateProvider'
'$urlRouterProvider'
($stateProvider, $urlRouterProvider) ->
$stateProvider.state 'events',
url: '/events/{id}'
templateUrl: 'templates/_event.html'
controller: 'EventsCtrl'
]
app.controller 'EventsCtrl', [
'$scope'
'$stateParams'
($scope, $stateParams) ->
console.log $stateParams //this never shows up
console.log 'Sup' //this never shows up
$scope.greeting = 'Yo' //neither does this
]
events.html.erb
<div ng-app="EventsApp">
Yo! //this shows up, but not {{greeting}}
{{greeting}}
<ui-view></ui-view>
</div>
_event.html
<script type="text/ng-template" id="/event.html">
<div>
{{greeting}}
Yo!
</div>
</script>
Rails routes file:
get "events/*path" => "events#events"
Rails events_controller.rb
class EventsController < ApplicationController
layout "application"
def events
end
end
File layout:
--app
-----assets
-------javascripts
----------templates
------------_event.html
----------events.coffee.erb
------views
--------events
----------events.html.erb
Your angular code is poorly structured. I think you are mixing up your Javascript syntax with your Ruby syntax...
Try something closer to this:
angular.module('EventsApp', ['ui.router', 'templates'])
.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider.state('events', {
url = '/events/{id}',
templateUrl: 'templates/_event.html',
controller: 'EventsCtrl'
}
}
])
.controller('EventsCtrl', [
'$scope', '$stateParams'
function($scope, $stateParams) {
console.log($stateParams);
console.log('Sup')
$scope.greeting = 'Yo';
}
]);
I have been all over the tutorial sites and couldn't get this working
I'm trying to make an angular app that works over the REST with my server(I downloaded this and managed to get it working but I started a new one from scratch to understand everything better). making the REST server was the easy part since I'm a php guy, but I'm not so familiar with angular part.
I made a simple directory with yeoman and put my REST server next to it in another folder, so I have :
root
------app with all angular code here
------engine which is a yii2 framework
in app/script/app.js I have:
'use strict'; // BTW what is this line doing?
var app = angular
.module('gardeshApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/post/index' , {
templateUrl: 'views/post/index.html',
controller : 'PostList'
})
.otherwise({
redirectTo: '/'
});
});
I wanted make some kind of Model object to put received data in, so I created a Post model like :
app.factory('Post' , ['$resource'] , function($resource){
var Post = $resource('http://localhost/testApp/engine/web/post/:id' , {id : '#id'} , {update: {method: 'PUT'}});
angular.extend(Post.prototype , {
save: function (values) {
if (values) {
angular.extend(this, values);
}
if (this.id) {
return this.$update();
}
return this.$save();
}
});
});
and a controller to fetch the data:
app
.controller('PostList', ['$scope', '$http' , '$resource',
function($scope, $http) {
// $http.get('http://localhost/testApp/engine/web/post').success(function(data){
// console.log(data); // this works fine and gets the json ed data
// });
var posts = new Post();
console.log(posts.query());
}]);
I don't want to call $http.get myself, I want to make it dynamic but the Error says Post is not defined.
how can I make a proper Post Object to represent the model I'm fetching?
You may do something like this:
app.factory('Post' , ['$resource'] , function($resource){
var Post = $resource('http://localhost/testApp/engine/web/post/:id',
{
update: {method: 'PUT'}
}
);
return Post;
});
And,
app.controller('PostList', ['$scope', '$http' , 'Post',
function($scope, $http, Post) {
console.log(Post.query());
}]);
You need to return your built object in a factory in order to make it dependency-injectable later. Then in your controller, you need to declare that your want Post, and Angular will inject it for you.
The following code:
$routeProvider
.when("/page1", { controller: "MyController", resolve: {Strategy: "StrategyOne"}})
waits for the Strategy dependency to be resolved before to instantiate the controller "MyController".
In my application I have a function which returns a promise, which when resolved, gives the current user. Let's called that function Authentication.currentUser()
I would like all the pages of my app to wait for that promise to be resolved before to render a page. I could happily add a line for each route declaration but I would rather avoid duplication.
I have a controller called 'MainCtrl' which is called for all pages thanks to this line in my template:
<html ng-app="clientApp" ng-controller="MainCtrl">
I think one possible way to address this would be if it was possible to specify Authentication.currentUser() as a dependency of "MainCtrl" at the controller level (not at the route level because this dependency does not depend on a particular route).
Thanks for your help guys!
For those who want to address this with the standard $routeProvider, this is what I came out with:
$rootScope.$on('$routeChangeStart', function (event, next, current) {
if (!next.resolve){ next.resolve = {} }
next.resolve.currentUser = function(Authentication){
return Authentication.currentUser();
};
});
If you can move from the default router, to ui-router, then you can do this with nested states. Just copying the example from https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#inherited-resolved-dependencies :
$stateProvider.state('parent', {
resolve:{
resA: function(){
return {'value': 'A'};
}
},
controller: function($scope, resA){
$scope.resA = resA.value;
}
})
.state('parent.child', {
resolve:{
resB: function(resA){
return {'value': resA.value + 'B'};
}
},
controller: function($scope, resA, resB){
$scope.resA2 = resA.value;
$scope.resB = resB.value;
}
I have built an test app very similar to the one from AngularJS' tutorial, with 1 major difference: It is initialized with Yeoman.
My factory code looks like this:
var deClashServices = angular.module('deClashServices', ['ngResource']);
deClashServices.factory('Session',
['$resource',
function ($resource) {
return $resource('views/sessions.json');
}]
);
Yes, angular-resource.js has been added to index.html. As well as my Controller, and Service js files.
Yes, deClashServices has been listed as a dependency on the ng-app, as seen here in my app.js:
var declashAngularApp = angular.module('declashAngularApp', [
'ngRoute',
'deClashServices',
'deClashControllers'
]);
declashAngularApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/sessions', {
templateUrl: 'views/sessions.html',
controller: 'SessionListCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);
and here is my Controller:
var deClashControllers = angular.module('deClashControllers', []);
deClashControllers.controller('MainCtrl',
['$scope', 'Session',
function ($scope, Session) {
$scope.sessions = Session.query();
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]
);
in main.html, which is under MainCtrl, {{awesomeThings}} produces the array of 3 strings, as expected.
But {{sessions}} produces an empty array.
To pinpoint that it is .query() that's not loading it, I tried using a factory with a simple JSON file: {"sessions":"number1"}
deClashServices.factory('Session',
['$resource',
function ($resource) {
return $resource('views/simple.json');
}]
);
And my controller is like this:
deClashControllers.controller('MainCtrl',
['$scope', 'Session',
function ($scope, Session) {
$scope.sessions = {};
Session.get(function(response) {
$scope.sessions = response.sessions;
});
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]
);
This code works. Switching back to the JSON array and trying a callback with .query.$promise.then(callback-function) however, does not work.
I'm pretty lost and confused now, as the tutorial code from AngularJS with almost the exact same structure works.
I suspect that there's something wrong in the way I'm using .query(), but at the same time the same way is used by the Angular Tutorial and there isn't a problem there.
Just in case that it might be outside the few code snippets I've shown, here in the code for the entire project:
github
Angular's resource-service doesnt return promise. It returns an empty object so that when the request returns from server resource-service can populate that object with fetched data because it has a reference to that object.
So if you want to react to returning data you have to use a callback function or better yet
use $http-service, because it return promise.
Look at this plkr
I also recommend you take a look at Restangular
I trying to get on my feet with angular.js using the seed app.
When the browser executes my controller i get the following error:
TypeError: Cannot set property 'players' of undefined
at new bankC (http://localhost:8888/monopoly/js/controllers.js:18:20)
at invoke (http://localhost:8888/monopoly/lib/angular/angular.js:2795:28)
at Object.instantiate (http://localhost:8888/monopoly/lib/angular/angular.js:2805:23)
at http://localhost:8888/monopoly/lib/angular/angular.js:4620:24
at update (http://localhost:8888/monopoly/lib/angular/angular.js:13692:26)
at http://localhost:8888/monopoly/lib/angular/angular.js:8002:24
at Array.forEach (native)
at forEach (http://localhost:8888/monopoly/lib/angular/angular.js:110:11)
at Object.Scope.$broadcast (http://localhost:8888/monopoly/lib/angular/angular.js:8000:11)
at http://localhost:8888/monopoly/lib/angular/angular.js:7185:26
this is the controller code which is the controller.js file
function bankC($scope) {
$scope.players = [
{
id: 0,
name: "Playe1",
balance: 1500
},
{
id: 1,
name: "Player2",
balance: 1500
},
{
id: 2,
name: "Player 3",
balance: 1500
}
];
}
bankC.$inject = [];
Thanks
EDIT:
its registered with angular js to be used when on a certain "page"
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: MyCtrl1});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: MyCtrl2});
$routeProvider.when('/bank', {templateUrl: 'partials/bank.html', controller: bankC});
$routeProvider.otherwise({redirectTo: '/bank'});
}]);
EDIT2:
Removing "bankC.$inject = [];" from the controller file solved the problem, so why does the angular.js seed app include it?
You are getting that error because of the last line
bankC.$inject = [];
This tells the angular injector to inject nothing into the controller while the controller is looking for $scope.
If you change this to
bankC.$inject = ['$scope'];
it should work fine.
That last line exists because angular uses Dependancy Injection. Angular looks for variables with name $scope when you request for it in a controller. But if the code is minified then the obfuscation will change the name of $scope to something else. In order to maintain sanity when this happens that last line is introduced. When ever you declare a new controller the best practice would be to include that last line with all the variables you want angulars DI to inject into that controller.
Note : If you are interested in getting more things injected into that controller ( or similiar controllers ) then you will have to update bankC.$inject as well.