I'm creating an Angular app on Grails 3.1.5 and asset pipeline is not giving me the Javascript file ordering I need. I have the following Javascript files:
angello.js
//= require /angular/angular
//= require /angular-route/angular-route
//= require /angello/core/angello.core
//= require /angello/index/angello.index
//= require /angello/common/angello.common
//= require /angello/storyboard/angello.storyboard
var myModule = angular.module("Angello", [
"angello.core",
"angello.index",
'ngRoute',
'Angello.Common',
'Angello.Storyboard'
]);
myModule.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'assets/angello/storyboard/tmpl/storyboard.html',
controller: 'StoryboardCtrl',
controllerAs: 'storyboard'
})
});
myModule.controller('MainCtrl', function() { });
angello.storyboard.js
//= require_tree services
//= require_tree controllers
//= require_tree directives
//= require_tree templates
//= require_self
angular.module('Angello.Storyboard', ['Angello.Common']);
storyboardController.js
//= require /angular/angular
//= require /angello/storyboard/angello.storyboard
//= require_self
angular.module('Angello.Storyboard')
.controller('StoryboardCtrl', function() {
var storyboard = this;
});
I include all of this in my main GSP with
<asset:javascript src="angello.js" /> When the HTML is rendered, the order of the JS files are not what I expect:
<script type="text/javascript" src="/assets/angular/angular.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angular-route/angular-route.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angular/angular-resource.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/core/angello.core.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/core/services/DomainServiceFactory.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/index/angello.index.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/index/services/applicationDataFactory.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/index/controllers/indexController.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angular/ui-bootstrap-tpls.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/common/angello.common.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/storyboard/controllers/storyboardController.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello/storyboard/angello.storyboard.js?compile=false" ></script>
<script type="text/javascript" src="/assets/angello.js?compile=false" ></script>
The problem is that storyboard JS files are included in the order opposite of what I need, resulting in angular complaining
Error: [$injector:nomod] Module 'Angello.Storyboard' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
I think this is a problem in the way I have structured the dependency directives. I have tried many different things, but nothing seems to affect the order.
The module which is used to create the artifacts like controller, service, etc has to be loaded first before the dependents are loaded. In the above case controllers are required before the module itself.
So, when the controller (styoryBoardController.js) is required it complains about the module not being present.
Moving //= require_self to the top in angello.storyboard.js will ensure that the module itself is required first then the dependencies.
Related
So I am making an AngularJS project and want to put my alasql functionality within a factory that I will inject into my controllers. However, I am getting a console error stating that alasql is not defined in my factory. Here is my code for some files:
// sqlFactory.js
angular.module('app').factory('sqlFactory', sqlFactory);
function sqlFactory() {
alasql("CREATE localStorage DATABASE IF NOT EXISTS db");
alaqsl("ATTACH localStorage DATABASE db");
alaqsl("USE db");
.......
}
I think I am handling the injection into the controller correctly:
// myController.js
angular.module("app").controller("myController", myController);
myController.$inject = ['sqlFactory'];
function myController(sqlFactory) {
....
}
And I am referencing the alasql file in my layout page, although maybe not in the correct order? :
<script type="text/javascript" src="~/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/alasql/0.4.3/alasql-worker.min.js"></script>
<script type="text/javascript" src="~/lib/angular/angular.min.js"></script>
<script type="text/javascript" src="~/js/app.js"></script>
<script type="text/javascript" src="~/js/sqlFactory.js"></script>
<script type="text/javascript" src="~/js/site.js"></script>
I am fairly new to using factories and alasql. Anyone know why it is coming back as undefined? Do I need to inject alasql into my factory?
I am creating an Angular App,
var app = angular.module("myApp", ["ngRoute","ngMaterial","ngMessages"]);
When i am using 'ngMessages' with 'ngMaterial', it is not working.
Make sure you have loaded them in the references with the correct versions ,
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.11.0/angular-material.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs//1.4.8/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<script src="app.js"></script>
DEMO
I have the following view rendered from my express server index.html
<section ng-view></section>
<!-- Load local libraries -->
<script type="text/javascript" src="/lib/angular/angular.js"></script>
<script type="text/javascript" src="/lib/angular-route/angular-route.js"></script>
<script type="text/javascript" src="/lib/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="/dummy/dummy.client.module"></script>
<script type="text/javascript" src="/dummy/dummy.client.controller"></script>
<script type="text/javascript" src="/dummy/dummy.client.route"></script>
<!-- Bootstrap AngularJS application -->
<script type="text/javascript" src="/application.js"></script>
I manually bootstrap it with application.js file:
var mainApplicationModule = angular.module('app', ['ngResource', 'ngRoute', 'dummy'])
mainApplicationModule.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('!');
}
]);
if (window.location.hash === '#_=_') window.location.hash = '#!';
// Manually bootstrap the AngularJS application
angular.element(document).ready(function() {
angular.bootstrap(document, ['app']);
});
Then in dummy.client.module.js:
angular.module('dummy', [])
in dummy.client.controller.js:
angular.module('dummy').controller('DummyController', ['$scope', function($scope) {
$scope.text = 'hi what '
}])
dummy.client.route.js:
angular.module('dummy').config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'dummy/dummy.client.view.html'
})
}])
dummy.client.view.html:
<section ng-controller="DummyController">
<textarea ng-bind="text"></textarea>
</section>
I get an empty page. the controller is not invoked (i use alert('hi') to test)
If i don't use ngRoute, i.e. append all the js files in the index.html page, it's working instead of using ngRoute and ng-view, it works
error message:
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module dummy due to:
Error: [$injector:nomod] Module 'dummy' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.3.0-build.3042+sha.76e57a7/$injector/nomod?p0=dummy
at chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:120:12
at chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:215:17
at ensure (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:139:38)
at module (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:213:14)
at angular.module (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:686:31)
at angular.module (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1019:38)
at http://localhost:3000/lib/angular/angular.js:3877:22
at forEach (http://localhost:3000/lib/angular/angular.js:325:18)
at loadModules (http://localhost:3000/lib/angular/angular.js:3871:5)
at http://localhost:3000/lib/angular/angular.js:3878:40
http://errors.angularjs.org/1.2.28/$injector/modulerr?p0=dummy&p1=Error%3A%…t%20http%3A%2F%2Flocalhost%3A3000%2Flib%2Fangular%2Fangular.js%3A3878%3A40
at http://localhost:3000/lib/angular/angular.js:78:12
at http://localhost:3000/lib/angular/angular.js:3905:15
at forEach (http://localhost:3000/lib/angular/angular.js:325:18)
at loadModules (http://localhost:3000/lib/angular/angular.js:3871:5)
at http://localhost:3000/lib/angular/angular.js:3878:40
at forEach (http://localhost:3000/lib/angular/angular.js:325:18)
at loadModules (http://localhost:3000/lib/angular/angular.js:3871:5)
at createInjector (http://localhost:3000/lib/angular/angular.js:3811:11)
at doBootstrap (http://localhost:3000/lib/angular/angular.js:1444:20)
at Object.angular.resumeBootstrap (http://localhost:3000/lib/angular/angular.js:1467:5)
http://errors.angularjs.org/1.2.28/$injector/modulerr?p0=app&p1=Error%3A%20…p%20(http%3A%2F%2Flocalhost%3A3000%2Flib%2Fangular%2Fangular.js%3A1467%3A5)angular.js:78 (anonymous function)angular.js:3905 (anonymous function)angular.js:325 forEachangular.js:3871 loadModulesangular.js:3811 createInjectorangular.js:1444 doBootstrapangular.js:1467 angular.resumeBootstraphint.js:535 maybeBootstrap
[Edit]:
I have tried another module and still not working:
article.client.module.js:
angular.module('article', [])
article.client.route.js:
angular.module('article').config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {templateUrl:'article/list-article.client.view.html'})
}
]);
article.client.controller:
angular.module('article').controller('ArticleController', ['$scope', function($scope) {
$scope.text = 'hi'
}
])
list-article.client.view.html:
<section ng-controller="ArticleController">
<textarea ng-bind="text"></textarea>
</section>
application.js:
//var mainApplicationModule = angular.module('app', ['ngResource', 'ngRoute', 'dummy']);
var mainApplicationModule = angular.module('app', ['ngResource', 'ngRoute', 'article']);
//var mainApplicationModule = angular.module('app', ['ngResource', 'ngRoute', 'article', 'user', 'index']);
mainApplicationModule.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('!');
}
]);
if (window.location.hash === '#_=_') window.location.hash = '#!';
// Manually bootstrap the AngularJS application
angular.element(document).ready(function() {
angular.bootstrap(document, ['app']);
});
<section ng-view></section>
<!-- Load local libraries -->
<script type="text/javascript" src="/lib/angular/angular.js"></script>
<script type="text/javascript" src="/lib/angular-route/angular-route.js"></script>
<script type="text/javascript" src="/lib/angular-resource/angular-resource.js"></script>
<!--<script type="text/javascript" src="/dummy/dummy.client.module.js"></script>-->
<!--<script type="text/javascript" src="/dummy/dummy.client.controller.js"></script>-->
<!--<script type="text/javascript" src="/dummy/dummy.client.route.js"></script>-->
<!-- Load the articles module -->
<script type="text/javascript" src="/article/article.client.module.js"></script>
<script type="text/javascript" src="/article/article.client.controller.js"></script>
<script type="text/javascript" src="/article/article.client.route.js"></script>
<!--<script type="text/javascript" src="/article/article.client.resource.js"></script>-->
<!-- Bootstrap AngularJS application -->
<script type="text/javascript" src="/application.js"></script>
I commented out the dummy module. same error as before
[Edit 2]:
if i change the folder name to article2 or anything other than 'article', then it works.
I think you are missing .js in the script include. Because of which dummy module is failed to initialize and consequently you get the mentioned error.
<script type="text/javascript" src="/dummy/dummy.client.module.js"></script>
<script type="text/javascript" src="/dummy/dummy.client.controller.js"></script>
<script type="text/javascript" src="/dummy/dummy.client.route.js"></script>
extended answer to extended question...
Now, there are two more problems here
article module is getting initialized as you are using ngRouteProvider in article module without adding ngRoute dependency.
//You need to add ngRoute dependency in order to use $ngRouteProvider
angular.module('article', ['ngRoute']);
for this you also need to include angular-route.js
refer : https://docs.angularjs.org/api/ngRoute
You are using ngResource in application.js but I do not see you are including angular-resource.js
refer: https://docs.angularjs.org/api/ngResource
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:modulerr] Failed to instantiate module ngGrid due to:
Error: [$injector:nomod] Module 'ngGrid' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
Above is the error message I received.
I have loaded the ng-grid script AFTER angularjs, jquery.
I injected it into app like this:
var myApp = angular.module('myApp', ['ui.bootstrap','ngRoute', 'ngResource','ngGrid'])
.controller('myAppCtrl', myAppCtrl);
I wonder where did I do wrong?
===UPDATE
Here is my header
<!-- Angular Libs -->
<script type="text/javascript" src="/library/angularjs/1.2.9/angular.js"></script>
<script type="text/javascript" src="/library/angularjs/1.2.9/angular-route.js"></script>
<script type="text/javascript" src="/library/angularjs/1.2.9/angular-resource.js"></script>
<!-- jQuery Libs -->
<script type="text/javascript" src="/library/jquery/2.1.1/jquery.js"></script>
<!-- Third-party Libs -->
<script type="text/javascript" src="/library/angular-ui/bootstrap/0.11.0/ui-bootstrap-tpls.js"></script>
<script type="text/javascript" src="/library/angular-ui/ng-grid3/2.0.7/ng-grid.js"></script>
They are all found. No error of 404 return in Chrome Inspector
USE ui.grid not ngGrid
yea. as stupid as it is. Confused by its official GetStarted lol
I was facing an error with ui-grid, I used the following ng-grid to solve.
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/ng-grid/2.0.11/ng-grid.min.css" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ng-grid/2.0.11/ng-grid.min.js"></script>
Having trouble rendering first page using rails and backbone. Please assume that I have all the gems properly installed and running. Most of the coffeescript files are generated using 'rails g backbone:scaffold Student', but I changed some files and directory structure. This is just to try to understand the process flow than anything else. I also loaded some student data in db. Finally, when this rails application is deployed (development) and I visit localhost:3000, I don't get the alert that is in initialize function.
Here are the files.
app/models/students.rb
class Student < ActiveRecord::Base
attr_accessible :dob, :email, :name, :phone_number
end
app/controllers/students_controller.rb
class StudentsController < ApplicationController
respond_to :html, :json
def index
respond_with (#students = Student.all)
end
end
config/routes.rb
School::Application.routes.draw do
resources :students
root :to => 'students#index'
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>School</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<tbody>
<div id="students">
<%= yield %>
</div>
</tbody>
</body>
</html>
app/views/students/index.html.erb
<%= content_for :javascript do %>
<%= javascript_tag do %>
window.School.initialize({ students: <%= #students.to_json %> });
<% end %>
<% end %>
app/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui-1.8.18.custom.min
//
//= require underscore
//= require json2
//= require backbone
//= require backbone_rails_sync
//= require backbone_datalink
//= require backbone-forms
//= require school
//= require_tree ./models
//= require_tree ./collections
//= require_tree ./views
//= require_tree ./routers
//= require_tree ../templates
//= require_tree .
app/assets/javascripts/school.js.coffee
#= require_self
#= require_tree ../templates
#= require_tree ./models
#= require_tree ./collections
#= require_tree ./views
#= require_tree ./routers
window.School =
Models: {}
Collections: {}
Routers: {}
Views: {}
initialize: (data) -> alert 'Hello for rails'
app/assets/javascripts/collections/students.js.coffee
class School.Collections.StudentsCollection extends Backbone.Collection
model: School.Models.Student
url: '/students'
app/assets/javascripts/models/student.js.coffee
class School.Models.Student extends Backbone.Model
paramRoot: 'student'
app/assets/javascripts/routers/students_router.js.coffee
class School.Routers.StudentsRouter extends Backbone.Router
initialize: (options) ->
#students = new School.Collections.StudentsCollection()
#students.reset options.students
routes:
"index" : "index"
".*" : "index"
index: ->
#view = new School.Views.Students.IndexView(students: #students)
$("#students").html(#view.render().el)
app/assets/javascripts/views/students/index_view.js.coffee
School.Views.Students ||= {}
class School.Views.Students.IndexView extends Backbone.View
template: JST["templates/students/index"]
initialize: () ->
#options.students.bind('reset', #addAll)
addAll: () =>
#options.students.each(#addOne)
addOne: (student) =>
view = new School.Views.Students.StudentView({model : student})
#$("tbody").append(view.render().el)
render: =>
#$el.html(#template(students: #options.students.toJSON() ))
#addAll()
return this
app/assets/templates/students/index.jst.ejs
<h1>Listing students</h1>
<table id="students-table">
<tr>
<th>Name</th>
<th>DOB</th>
<th>Email</th>
</tr>
</table>
html output
<!DOCTYPE html>
<html>
<head>
<title>School</title>
<link href="/assets/application.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/students.css?body=1" media="all" rel="stylesheet" type="text/css" />
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery-ui-1.8.18.custom.min.js?body=1" type="text/javascript"></script>
<script src="/assets/underscore.js?body=1" type="text/javascript"></script>
<script src="/assets/json2.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone_rails_sync.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone_datalink.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-forms.js?body=1" type="text/javascript"></script>
<script src="/assets/school.js?body=1" type="text/javascript"></script>
<script src="/assets/students/edit.js?body=1" type="text/javascript"></script>
<script src="/assets/students/index.js?body=1" type="text/javascript"></script>
<script src="/assets/students/new.js?body=1" type="text/javascript"></script>
<script src="/assets/students/show.js?body=1" type="text/javascript"></script>
<script src="/assets/students/student.js?body=1" type="text/javascript"></script>
<script src="/assets/models/student.js?body=1" type="text/javascript"></script>
<script src="/assets/collections/students.js?body=1" type="text/javascript"></script>
<script src="/assets/views/students/edit_view.js?body=1" type="text/javascript"></script>
<script src="/assets/views/students/index_view.js?body=1" type="text/javascript"></script>
<script src="/assets/views/students/new_view.js?body=1" type="text/javascript"></script>
<script src="/assets/views/students/show_view.js?body=1" type="text/javascript"></script>
<script src="/assets/views/students/student_view.js?body=1" type="text/javascript"></script>
<script src="/assets/routers/students_router.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="46vcYK8H3HIUfZh9wfu+AtzCKs+/2TnESA2ILxhFx0E=" name="csrf-token" />
</head>
<body>
<tbody>
<div id="students">
</div>
</tbody>
</body>
</html>
You have a couple of problems that are seemingly related and unrelated at the same time.
The reason your index doesn't render correctly is because you have a content block for a a named yield that doesn't exist.
To get <%= content_for :javascript do %> to work, add the following to application.html.erb:
<%= yield :javascript %>
However, this will get your code to display, it most likely will not get it to run correctly.
Since you are using the rails-backbone gem and leveraging the use of templates, you simply need to have the following in your index.html.erb:
<div id="students"></div>
And then instantiate your backbone router in your index.html.erb by using:
<script type="text/javascript">
$(function(){
try {
window.SchoolRouter = new School.Routers.StudentsRouter({ students: <%= #students.to_json %> });
backbone.history.start();
}catch(e){
alert(e); // alert so that you see it.
}
});
</script>
When it comes to JavaScript, make sure you're using FireBug or the Dev panels in your browser. console.log() is your best friend.