I have an existing angular/rails app. Everything works fine, except I just added a new module, and the template will not render. Below is my code.
views/printers/orders_index.html.erb
<div ng-app="printers">
<div ui-view></div>
</div>
assets/javascripts/printers/config.js
(function() {
'use strict'
angular.module('printers.controller', [])
angular
.module('printers',
['ngAnimate',
'ui.router',
'templates',
'ngResource',
'printers.controller',
'orders.factories'
])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
/* Routes and States*/
$stateProvider
.state('printers.orders.index', {
url: '/printer_orders_index',
templateUrl: 'orders_index.html',
controller: 'PrintersController'
})
// default fall back route
$urlRouterProvider.otherwise('printers_orders_index')
})
})()
assets/javascripts/printers/controllers/printers_controllers.js
(function() {
'use strict'
angular
.module('printers.controller')
.controller("PrintersController", PrintersController)
PrintersController.$inject = ['$scope', 'Order']
function PrintersController($scope, Order){
Order.query({}, function(response){
$scope.orders = response.orders
$scope.printer_id = response.meta.printer_id
})
}
})()
assets/templates/orders_index.html
(this will not render, it seems it is only rendering the orders_index.html.erb, and the ng-app=printers is not doing anything.)
Meow(h1 tags with Meow in between)
I have tried the sprockets issue, but it has been fixed, i cant think of anything else. Any help would be soooo greatly appreciated!
Related
I have and angularjs app.I want to concatenate all the JS files to a single file.I'm currently trying to use Grunt.js to setup an automatic build process for concatenating JavaScript files.
However my app runs without any error before concatenation.But after concatinating the files my app throws Error: $injector:modulerr
Module Error.
Below is my code after minification
angular.module('myApp', []);
var app = angular
.module('myApp', [
'ngRoute'
]);
app.config(function ($routeProvider) {
'use strict';
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'mainCntrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'aboutCntrl',
controllerAs: 'about'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('mainCntrl',['$scope', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]);
app.controller('aboutCntrl',['$scope', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
}]);
Any help appreciated.Thanks :)
You need to strictly follow either Inline Array Annotation of DI or $inject Property Annotation while minifying js files.
app.config(function ($routeProvider) {
'use strict';
//code
});
should be changed to below code.
Inline Array Annotation
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
//code as is
}]);
$inject Property Annotation
var config = function($routeProvider) {
'use strict';
//code as is
}
config.$inject = ['$routeProvider'];
app.config(config);
Seems like the config line is your problem, try app.config(['$routeProvider', function ($routeProvider) { ... }]);
Yes, your annotation is not right. It should be
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
//code
}]);
Use ng-annotate as a safe, clean and simple solution.
What it does is that when you grunt it'll annotate your definitions the proper way, so you don't have to deal with Angular's quirky way.
Run ng-annotate on
app.config(function($routeProvider) {
'use strict';
//code
});
and it'll auto-complete it for minification:
app.config(["routeProvider", function($routeProvider) {
'use strict';
//code
}]);
You can also add another step to your build workflow - grunt-ng-annotate in that case you will be able to skip almost all strict DI annotations. With this plugin you can simplify services/controllers definitions e.g.:
app.controller('mainCntrl', function ($scope) {
'use strict';
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
});
It is extremely helpful when you heave a long list of services to inject into controller or another service. You don't have to remember to put each dependency twice.
I am trying to inject $httpParamSerializer for use in templateUrl but I am having some issues. There isn't any good documentation and examples of how to use $httpParamSerializer.
Example code:
angular.module('myApp', ['ngRoute']).config(
function($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
.when('/data/dashboard', {
templateUrl: function(params) {
//NEED TO USE IT HERE
}
})
})
Things that didn't work, placing it like this:
function($routeProvider, $locationProvider, $httpProvider,$httpParamSerializer ) {
Also in the moduler, like this:
angular.module('myApp', ['ngRoute', '$httpParamSerializer']).config(
Any insight why this isn't working would help.
Since you're in the config you need to get it from the provider itself. That is, inject the provider and call $get
angular.module('myApp', ['ngRoute']).config(
function($routeProvider, $locationProvider, $httpProvider, $httpParamSerializerProvider) {
// get the serializer from the provider
var paramSerializer = $httpParamSerializerProvider.$get();
console.log(paramSerializer({a:1})); // test it
$routeProvider.when('/', {
templateUrl: function(params) {
// you can use paramSerializer(here
}
});
});
Working version of your jsfiddle: http://jsfiddle.net/kh9oeq1y/16/
This forum suggests it's a problem with your angular version. Check that you're using at least 1.4.0.
I have a problem with adding a Angular controller to my HTML view. The angular way of doing this is: ng-controller="<controller>". But because I am using RequireJs I have to do this in a different way. I have to add a sub page to every controller and view:
define(['app', 'login/LoginController'], function (app, LoginController) {
app.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/', {
templateUrl: "modules/" + 'login/login.html',
controller: LoginController
});
});
app.controller('LoginController', LoginController);
});
This way I can define my where my controller is and where my view is.
Problem
Now I have a header.html in which I want to include a menu.html. this can be done via: ng-include="'modules/menu/menu.html'". This works fine. But how can I add a controller to this menu.html?
I have tried: ng-controller="MenuController" but then I get the error: 'Error: [ng:areq] Argument 'MenuController' is not a function, got undefined'. So I do not know how I should add a controller to my menu.html with RequireJS.
MenuController
my MenuController looks as follows:
define(['$'], function ($) {
'use strict';
var MenuController = function ($location, menu, $scope) {
$scope.info="testing123";
};
return MenuController;
});
Anyone knows how I should do this?
You can for example use multiple views in the same controllerwith $stateProvider:
app.config(function ($stateProvider, $locationProvider) {
$stateProvider
.state('login', {
url: '/',
views: {
'menu': {
templateUrl: 'modules/menu/menu.html',
controller: MenuController
},
'login': {
templateUrl: 'modules/login/login.html'
controller: LoginController
}
}
});
});
Then in your template to call them you just need to do something like:
<div ui-view="menu"></div>
<div ui-view="login"></div>
You can see more info on github ui-router.
I want to use lazy loading in my Angular project:
This is the relevant app.js code:
var app = angular.module('eva', ['ui.router',
'controllers', 'oc.lazyLoad']);
app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', '$locationProvider', '$ocLazyLoadProvider',
function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider, $ocLazyLoadProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
$urlRouterProvider.otherwise("/");
$locationProvider.hashPrefix('!');
$stateProvider.state('challenge', {
url: '/challenges',
templateUrl: 'views/Challenges.html',
controller: 'ChallengeCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}],
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load('js/controllers/ChallengeController.js');
}]
}
This is my controller definition code:
angular.module('eva').controller('ChallengeCtrl', ['$scope', 'auth','$translate', 'challengeFactory', 'userFactory', 'userService',
function($scope, auth, $translate, challengeFactory, userFactory, userService) {
I am not loading the challengecontroller.js file in the index.html file.
I include oclazyload just before app.js in the index.html file:
<script type="text/javascript" src="js/lib/oclazyload/dist/ocLazyLoad.js"></script>
<script type="text/javascript" src="js/app.js"></script>
I get this error now when I run the app:
Error: [ng:areq] http://errors.angularjs.org/1.4.7/ng/areq?p0=ChallengeCtrl&p1=not%20a%20function%2C%20got%20undefined
I tried many things for lazy loading, none of them worked. Now I just followed the example on Example
I really am in a pickle here, and I have no clue what to do to get the lazy loading working. I rather not work with requirejs.
angular config is just a function, any dependencies should be already $inject before you call this config. you may include it in <script> tag and add it to app = angular.module['app', ['depend1'])
so you change it and try it again.
app.config(function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider, $ocLazyLoadProvider) {
btw: open your Browser Dev-Tools, to check whether this file js/controllers/ChallengeController.js is loadead correctly
As I felt my single controller was growing too large I am now trying to make use of multiple controllers. However, my UserController can't be found for some reason when I navigate to /signup. I'm getting this error:
Error: [ng:areq] Argument 'UserController' is not a function, got undefined
app.js
var app = angular.module('myApp', [
'ui.router',
'ngResource',
'myApp.controllers',
]);
angular.module('myApp.controllers', []);
app.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$stateProvider
.state('signup', {
url: '/signup',
templateUrl: 'views/signup.html',
controller: "UserController"
});
});
I'm including the .js files in this order:
<script src="angular/controllers/mainCtrl.js"></script> //binded to body tag
<script src="angular/controllers/userCtrl.js"></script> //set in signup state
<script src="angular/app.js"></script>
UserController
angular.module('myApp.controllers').controller('UserController', function () {
//do stuff
});
What am I missing?
Make it easier on yourself and create cleaner code.
var app = angular.module('myApp', [
'ui.router',
'ngResource',
'myApp.controllers',
])
.config(function($stateProvider) {
$stateProvider
.state('signup', {
url: '/signup',
templateUrl: 'views/signup.html',
controller: "UserController"
});
});
you weren't using $urlRoutProvider and $httpProvider so why inject them?
Angular Modules are good for nothing...so far. Except for loading 3rd-party angular code into your app and mocking during testing. Other than that, there is no reason to use more than one module in your app.
To create your UserController do a
app.controller('UserController', function ($scope) {
//do stuff
});
<script src="angular/controllers/mainCtrl.js"></script> //binded to body tag
<script src="angular/controllers/userCtrl.js"></script> //set in signup state
<script src="angular/app.js"></script>
You cant use a module before it's declared.so switch the scripts order.
You should stick to 1 independent module declaration per file and you'll be fine,otherwise you'll have to manage script order.
Your app.js has to be declared first like below BEFORE you pull in its controller subcomponents:
<script src="angular/app.js"></script>
<script src="angular/controllers/mainCtrl.js"></script> //binded to body tag
<script src="angular/controllers/userCtrl.js"></script> //set in signup state