I am trying to create a very simple Angular + Require project template.
I am getting error-
Error: Script error for: ngRoute
http://requirejs.org/docs/errors.html#scripterror
In my index.html i have
require(
[
'jquery',
'angular',
'mainApp',
], function($, angular, mainApp) {
var AppRoot = angular.element(document.getElementById('CollectorWallApp'));
AppRoot.attr('ng-controller','MainController');
angular.bootstrap(AppRoot, ['MainApp']);
});
In mainApp.js i'm doing the following-
'use strict';
define(['angular','ngRoute'],function(angular,ngRoute){
var MainApp = angular.module('MainApp',['ngRoute']);
MainApp.controller("MainController", function ($scope) {
console.log("Main Controller working");
});
//Route configuration goes here
MainApp.config([ '$routeProvider', function ($routeProvider) {
console.log("--->checkiing out $routeProvider");
}]);
return MainApp;
});
In Require config
'paths': {
'angular': 'js/lib/angular/angular',
'ngRoute': 'js/lib/angular-route.min',
.
.
.
.
.
'shim': {
'angular': {
exports: 'angular',
},
'ngRoute': {
exports: 'ngRoute',
deps: ['angular']
},
Unable to debug or pin point the reason.
Note- all my require paths are correct. Kindly help. Thanks
Related
I am trying to get the authentication of auth0 ( with my nodejs and angularjs(1.6.9) app. The backend already works so now I am trying to do the same in the frontend. I use requirejs to load all the necessary files. I already used this workaround here to fix the "auth0 is not defined" failure. Now the auth0 is defined, so angular-auth0 is supposed to work as well. Unfortunately it seems like the provider is somehow not working, it is undefined when I call the init() function. I hope sombedoy has an idea... Thanks in advance!
This is my error message:
jquery.min.js:2 Uncaught Error: [$injector:modulerr] Failed to instantiate module timemanagement due to:
TypeError: Cannot read property 'init' of undefined
at http://localhost:3000/js/app.js:12:38
at Object.invoke (http://localhost:3000/vendor/angular/angular.js:5106:19)
at runInvokeQueue (http://localhost:3000/vendor/angular/angular.js:4993:35)
at http://localhost:3000/vendor/angular/angular.js:5003:11
[...]
main.js
require.config({
baseUrl: "",
// alias libraries paths
paths: {
//Frameworks
'angular': 'vendor/angular/angular',
'angular-route': 'vendor/angular/angular-route',
'angular-uiroute': 'vendor/angular/angular-ui-router.min',
'angular-resource': 'vendor/angular/angular-resource',
'angular-de': 'vendor/angular/angular-locale_de-de',
'auth0-variables': 'vendor/replace/auth0-variables',
'lock': 'vendor/angular/lock.min',
'svg-assets-cache': 'vendor/angular/svg-assets-cache',
'angular-datepicker': 'vendor/angular/angular-datepicker',
'jquery': 'vendor/jquery/jquery.min',
'bootstrap-bundle': 'vendor/bootstrap/js/bootstrap.bundle.min',
'jquery-easing': 'vendor/jquery-easing/jquery.easing.min',
'sb-admin': 'js/sb-admin.min',
"auth0-js": "vendor/replace/auth0",
"preauth0": "js/preauth0",
"auth0.auth0": "vendor/angular/angular-auth0",
//Controllers
[....],
},
shim: {
'app': ['auth0-js'],
"auth0-js": {
"exports": "Auth0"
},
"auth0.auth0":{
'deps':["angular", "auth0-js", "preauth0"],
},
'angular-de': ['angular-datepicker'],
'angular-datepicker': ['angular-uiroute'],
'angular-uiroute': ['angular-route'],
'angular-route': ['angular-resource'],
'angular-resource': ['angular'],
'angular': {
'deps':['auth0-variables'],
'exports': 'angular'
},
'auth0-variables': ['sb-admin',],
'sb-admin': ['jquery', 'jquery-easing', 'bootstrap-bundle',]
},
// kick start application
deps: ['app']
});
preauth0.js
define(function (require) {
auth0 = require('auth0-js');
});
app.js
define(['angular', 'angular-route', 'angular-uiroute', 'angular-resource',
'angular-datepicker', 'auth0-js', 'auth0.auth0'], function () {
var app = angular.module("timemanagement", ['ngRoute', 'ui.router', 'ngResource',
'720kb.datepicker', 'auth0.auth0']);
app.config(['$routeProvider', '$urlRouterProvider', '$controllerProvider', '$provide',
'$stateProvider', 'angularAuth0Provider', function ($routeProvider, $urlRouterProvider,
$controllerProvider, $provide, $stateProvider, $resource, angularAuth0Provider) {
angularAuth0Provider.init({
clientID: AUTH0_CLIENT_ID,
domain: AUTH0_DOMAIN,
responseType: 'token id_token',
audience: 'https://' + AUTH0_DOMAIN + '/userinfo',
redirectUri: AUTH0_CALLBACK_URL,
scope: 'openid'
});
In this plunk I have a sample code running Angular + Angular UI Router + RequireJS. There are two pages, each with a corresponding controller. If you click on View 1, you should see a page that contains a directive.
When the page loads it throws the following exception:
Cannot read property 'controller' of undefined at at my-ctrl-1.js:3
meaning that app is undefined in my-ctrl-1.js even though I'm returning it in app.js. What's wrong with this code?
HTML
<ul class="menu">
<li><a href ui-sref="view1">View 1</a></li>
<li><a href ui-sref="view2">View 2</a></li>
</ul>
<div ui-view></div>
main.js
require.config({
paths: {
'domReady': 'https://cdnjs.cloudflare.com/ajax/libs/require-domReady/2.0.1/domReady',
'angular': 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min',
"uiRouter": "https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router"
},
shim: {
'angular': {
exports: 'angular'
},
'uiRouter':{
deps: ['angular']
}
},
deps: [
'start'
]
});
start.js
define([
'require',
'angular',
'app',
'routes'
], function (require, angular) {
'use strict';
require(['domReady!'], function (document) {
angular.bootstrap(document, ['app']);
});
});
app.js
define([
'angular',
'uiRouter',
'my-ctrl-1',
'my-ctrl-2',
'my-dir-1'
], function (angular) {
'use strict';
console.log("app loaded");
return angular.module('app', ['ui.router']);
});
my-ctrl-1.js
define(['app'], function (app) {
'use strict';
app.controller('MyCtrl1', function ($scope) {
$scope.hello = "Hello1: ";
});
});
The problem is that you have a circular dependency between app.js and my-ctrl-1.js. When RequireJS encounters a circular dependency, the references it passes to the modules' factories are going to be undefined. There are many ways to solve the issue. One simple way that would work with the code you show could be to change my-ctrl-1.js to:
define(function () {
'use strict';
return function (app) {
app.controller('MyCtrl1', function ($scope) {
$scope.hello = "Hello1: ";
});
};
});
And in app.js:
define([
'angular',
'my-ctrl-1',
'my-ctrl-2',
'my-dir-1',
'uiRouter',
], function (angular, ctrl1) {
'use strict';
console.log("app loaded");
var app = angular.module('app', ['ui.router']);
ctrl1(app);
return app;
});
Presumably, you'll have to do the same thing with your other controler.
The documentation has a section on the topic of circular dependencies and other methods to handle them.
I have a problem implementing Toaster into my demoApp which uses RequireJS. Here some code:
(function () {
require.config({
paths: {
'angular': 'bower_components/angular/angular',
'jquery': 'bower_components/jquery/dist/jquery',
'toaster': 'bower_components/toaster/toaster'
},
shim: {
angular: {
deps: ['jquery'],
exports: 'angular'
},
toaster: {
deps: ['angular', 'jquery'],
exports: 'toaster'
}
}
});
require([
'angular',
'app',
'toaster',
'jquery'
],
function (angular, app, toaster) {
'use strict';
// toaster is undefined. I add it here just for a check. <<<<<<
angular.bootstrap(angular.element('body')[0], ['myApp']);
});
})();
This is main.js and toaster is undefined where I wrote the comment near the end. The file is loaded as I can see it at the Sources tab in the console.
In addition, wherever I want to use toaster, it is undefined. Here some code from the same demo app:
First case:
define(['somefile', 'toaster'], function (someModule, toaster) {
'use strict';
// toaster is undefined
});
Second case (John Papa Angular Style Guide):
define(['somefile', 'toaster'], function (someModule) {
'use strict';
someModule.controller('NewController', NewController);
NewController.$inject = ['someDeps', 'toaster'];
function NewController(someDeps, toaster) {
// angular.js:13424 Error: [$injector:unpr]
// Unknown provider: toasterProvider <- toaster <- NewController
}
});
Here's what I'm using:
Angular: 1.5.3
RequireJs: 2.2.0
Toaster: 2.0.0
Can anyone tell me what I'm doing wrong?
You have to distinguish between Angular modules and RequireJS modules. Toaster only registers an Angular module, no need to export anything in a RequireJS way.
shim: {
// ...
toaster: {
deps: ["angular", "jquery"]
}
}
Bootstrapping:
require(["angular", "app"], function (angular) {
// here, app.js is loaded in the DOM, so you can bootstrap Angular:
angular.bootstrap(angular.element("body")[0], ["myApp"]);
})
In your app.js:
define(["toaster" /* , ... */], function () {
// here, toaster.js is loaded in the DOM, so you can add the "toaster" Angular module in your Angular app dependencies:
return angular.module("myApp", ["toaster" /* , ... */]);
});
Anywhere else:
define(["app"], function (app) {
// as myApp depends on toaster, you can inject the toaster service the Angular way:
app.controller("MyController", ["toaster", function (toaster) {
// ...
}]);
});
I had my angularjs app setup in local and everything was working fine till I upload my code to the staging server. I now have issue with dependencies that are not respected but I can't see why. I guess it was working in local because it was loading the library faster. I now modified my app to try to fix this issue but can't manage to make it work.
My application is loading a single page app, composed of 3 views (main, map and map-data). I'm using AngularJS modules structure to launch this app. Here is my directory structure:
The index.html is pretty basic:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0" />
<title>Map Application</title>
<link rel="icon" sizes="16x16" href="/favicon.ico" />
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key={{ map_key }}&sensor=false"></script>
<script type="text/javascript" src="/js/bower_components/requirejs/require.js"></script>
<link rel="stylesheet" href="/css/main.css" media="screen" type="text/css">
<link rel="stylesheet" href="/js/bower_components/bootstrap/dist/css/bootstrap.css">
</head>
<body>
<!-- Content -->
<div id="content" data-ui-view></div>
<script>
// obtain requirejs config
require(['require', 'js/require-config'], function (require, config) {
// set cache beater
config.urlArgs = 'bust=v{{ version }}';
// update global require config
window.require.config(config);
// load app
require(['main']);
});
</script>
</body>
</html>
Then requirejs-config.js:
if (typeof define !== 'function') {
// to be able to require file from node
var define = require('amdefine')(module);
}
define({
baseUrl: 'js', // Relative to index
paths: {
'jquery': 'bower_components/jquery/dist/jquery.min',
'underscore': 'bower_components/underscore/underscore-min',
'domReady': 'bower_components/requirejs-domready/domReady',
'propertyParser': 'bower_components/requirejs-plugins/src/propertyParser',
'async': 'bower_components/requirejs-plugins/src/async',
'goog': 'bower_components/requirejs-plugins/src/goog',
'angular': 'bower_components/angular/angular',
'ngResource': 'bower_components/angular-resource/angular-resource',
'ui.router': 'bower_components/angular-ui-router/release/angular-ui-router',
'angular-google-maps': 'bower_components/angular-google-maps/dist/angular-google-maps',
'moment': 'bower_components/momentjs/moment',
'moment-timezone': 'bower_components/moment-timezone/moment-timezone',
'moment-duration-format': 'bower_components/moment-duration-format/lib/moment-duration-format'
},
shim: {
'angular': {
exports: 'angular'
},
'ngResource': ['angular'],
'ui.router' : ['angular']
}
});
Then the main.js:
/**
* bootstraps angular onto the window.document node
* NOTE: the ng-app attribute should not be on the index.html when using ng.bootstrap
*/
define([
'require',
'angular',
'./app'
], function (require, angular) {
'use strict';
/**
* place operations that need to initialize prior to app start here
* using the `run` function on the top-level module
*/
require(['domReady!'], function (document) {
angular.bootstrap(document, ['app']);
});
});
Then the app.js:
/**
* loads sub modules and wraps them up into the main module
* this should be used for top-level module definitions only
*/
define([
'angular',
'ui.router',
'./config',
'./modules/map/index'
], function (ng) {
'use strict';
return ng.module('app', [
'app.constants',
'app.map',
'ui.router'
]).config(['$urlRouterProvider', function ($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
}]);
});
Here you can see that the app.js depends on the ./modules/map/index, where I'm loading all available controllers:
/**
* Loader, contains list of Controllers module components
*/
define([
'./controllers/mainCtrl',
'./controllers/mapCtrl',
'./controllers/mapDataCtrl'
], function(){});
Each controller are requesting the same kind of module, here is mapDataCtrl.js which is the one that is triggered by /:
/**
* Map Data controller definition
*
* #scope Controllers
*/
define(['./../module', 'moment'], function (controllers, moment) {
'use strict';
controllers.controller('MapDataController', ['$scope', 'MapService', function ($scope, MapService)
{
var now = moment();
$scope.data = {};
$scope.data.last_update = now.valueOf();
$scope.data.time_range = '<time range>';
$scope.data.times = [];
var point = $scope.$parent.map.center;
MapService.getStatsFromPosition(point.latitude, point.longitude).then(function(data){
$scope.data.times = data;
});
}]);
});
As you can see, the controller is requesting module.js where the states and module name are defined:
/**
* Attach controllers to this module
* if you get 'unknown {x}Provider' errors from angular, be sure they are
* properly referenced in one of the module dependencies in the array.
* below, you can see we bring in our services and constants modules
* which avails each controller of, for example, the `config` constants object.
**/
define([
'angular',
'ui.router',
'../../config',
'underscore',
'angular-google-maps',
'./services/MapService'
], function (ng) {
'use strict';
return ng.module('app.map', [
'app.constants',
'ui.router',
'angular-google-maps'
]).config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
$stateProvider
.state('main', {
templateUrl: '/js/modules/map/views/main.html',
controller: 'MainController'
})
.state('main.map', {
templateUrl: '/js/modules/map/views/main.map.html',
controller: 'MapController',
resolve: {
presets: ['MapService', function(MapService){
return MapService.getPresets();
}],
courses: ['MapService', function(MapService){
return MapService.getCourses()
}]
}
})
.state('main.map.data', {
url: '/',
templateUrl: '/js/modules/map/views/main.map.data.html',
controller: 'MapDataController'
})
;
//$locationProvider.html5Mode(true);
}]);
});
It's in this file that I have an issue. I'm trying to load the module angular-google-maps because I need it in my MapCtr controller and most probably in MapDataCtrl. But I get the following message:
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module app.map due to:
Error: [$injector:modulerr] Failed to instantiate module angular-google-maps due to:
Error: [$inj...<omitted>...1)
I have no idea what I am missing, for me everything looks tied correctly. What am I missing?
UPDATE 1
I think it's because angular-google-map is not AMD compliant, so I've modified my requirejs-config.js as follow:
if (typeof define !== 'function') {
// to be able to require file from node
var define = require('amdefine')(module);
}
define({
baseUrl: 'js', // Relative to index
paths: {
...
'underscore': 'bower_components/underscore/underscore-min',
'angular-google-maps': 'bower_components/angular-google-maps/dist/angular-google-maps',
...
},
shim: {
'angular': {
exports: 'angular'
},
'ngResource': ['angular'],
'ui.router' : ['angular'],
'angular-google-maps': {
deps: ["underscore"],
exports: 'angular-google-maps'
}
}
});
but I still have the same issue.
We can use an js library with require.js.There is no need to remove require.js. I still need to check why require.js config not working.
Meanwhile you can try this way.
// requirejs-config.js
define({
baseUrl: 'js', // Relative to index
paths: {
'jquery': 'bower_components/jquery/dist/jquery.min',
'underscore': 'bower_components/underscore/underscore-min',
'domReady': 'bower_components/requirejs-domready/domReady',
'propertyParser': 'bower_components/requirejs-plugins/src/propertyParser',
'async': 'bower_components/requirejs-plugins/src/async',
'goog': 'bower_components/requirejs-plugins/src/goog',
'angular': 'bower_components/angular/angular',
'ngResource': 'bower_components/angular-resource/angular-resource',
'ui.router': 'bower_components/angular-ui-router/release/angular-ui-router',
'angular-google-maps': 'bower_components/angular-google-maps/dist/angular-google-maps',
'moment': 'bower_components/momentjs/moment',
'moment-timezone': 'bower_components/moment-timezone/moment-timezone'
},
shim: {
'angular': {
exports: 'angular'
},
'ngResource': ['angular'],
'ui.router' : ['angular']
}
});
// google-map.js
define(['underscore', 'angular-google-maps'], function(){
});
And then requiring the module each time I need the map:
require(['google-map'], function(){
});
https://github.com/angular-ui/angular-google-maps/issues/390
I went through this tutorial. Now I am attempting incorporate require
I found this explanation.
I am currently getting an error
Object #<Object> has no method 'unshift'
Here is the code that is causing the error
require(['jquery', 'angular', 'app/routes/app'], function ($, angular, mainRoutes) {
//tried this way as well
//$(function () { // using jQuery because it will run this even if DOM load already happened
// angular.bootstrap(document, ['mainApp']);
//});
require(['Scripts/app/modules/mainApp.js'], function (mainApp) {
angular.bootstrap(document.body, [mainApp]);//based of orginal answer
})
});
my app.js file
define(['app/modules/mainApp', 'app/controller/controllers'], function (mainApp) {
return mainApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'Templates/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'Templates/phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
});
and my mainApp.js file
define(['angular', 'angular-resource'], function (angular) {
return angular.module('mainApp', ['ngResource']);
});
there are other files that I didnt show (controllers, services) but I dont think the problem lies their
UPDATE
I am now getting an error of undefined injector.
This is the only break point that gets hit, but the item is not undefined.
UPDATE 2
I updated my project to more resemble this
my main.js now is this
require.config({
baseUrl: '/Scripts/',
urlArgs: "bust=" + (new Date()).getTime(),
paths: {
'jquery': 'lib/require-jquery',
'angular': 'lib/angular/angular.min',
'angular-resource': 'lib/angular/angular-resource.min',
},
shim: {
'angular': { 'exports': 'angular' },
'angular-resource': { deps: ['angular'] },
'jQuery': { 'exports': 'jQuery' },
},
priority: [
'angular'
]
});
require(['angular', 'app/modules/app', 'app/routes/routes'], function (angular, app, routes) {
var $html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function () { //breakpoint here
$html.addClass('ng-app');
angular.bootstrap($html, [app.name]);
});
});
if i put a break point on angular element and run a test in console
(app == routes)
true
should app be equal to routes?
The second argument of bootstrap method should be an array, I made the change on the code below.
require(['jquery', 'angular', 'app/routes/app'], function ($, angular, mainRoutes) {
//tried this way as well
//$(function () { // using jQuery because it will run this even if DOM load already happened
// angular.bootstrap(document, ['mainApp']);
//});
require(['Scripts/app/modules/mainApp.js'], function (mainApp) {
angular.bootstrap(document.body, [mainApp]);
})
});