Angular App works great but ngMock NOT loading Modules properly - javascript

My app works fine when i deploy it and run it in a browser
I can successfully reach all my controllers/services. and they were linked together via submodules.
I used submodules to organize the states/routes better for ui-router. (Previously we had ALL of our states in the app dot js file. There were like 50. Now they're organized out into smaller modules).
app.js [Module file]
var phpApp = angular.module("phpApp",
[
"ui-router"
"phpApp.components" , ...
]).config(...).run(...);
components.js [Module file, contains states/routes]
var ComponentModule = angular.module("phpApp.components",
[
"ui-router"
"phpApp.components.user" ,
"phpApp.components.client"
...
]).config(...).run(...);
user.js [Module file, contains states/routes]
var UserModule = angular.module("phpApp.components.user",
[
"ui-router"
]).config(...).run(...);
user-controller.js // LOADS fine; is a controller.
angular.module('phpApp.components').controller('UserController', ....);
client-controller.js // does NOT load! Cannot find 'phpApp.components' module...
angular.module('phpApp.components').controller('ClientController', ...);
My index.html file loads the scripts in this order:
<script src="app.js"></script>
<script src="components/components-module.js"></script>
<script src="components/user/user-module.js"></script>
<script src="components/client/client-module.js"></script>
...
<script src="components/user/user-controller.js"></script>
<script src="components/client/**client-controller.js**"></script>
I dont get it. My client-controller loads AFTER my user-controller... yet it is not able to locate the proper module?
I get the error:
Uncaught Error: [$injector:nomod] Module 'phpApp.components'
is not available! You either misspelled the module name or
forgot to load it.
I am very confused and frustrated at this point. I am not sure where I am going wrong.

The answer lies in the karma config file (karma.conf.js by default)
The answer, as expected, was a simple one.
I had a rule to include all JavaScript files:
"app/app.js",
"app/components/**/*.js",
You will need to make sure you rewrite your load rules to load all module JS files first:
"app/app.js",
"app/components/**/*-module.js", <-- modules must load first
"app/components/**/*.js",
To help expound, i have my project set up where:
1) controllers are in their respective xxx-controller.js files,
2) ervices are in xxx-service.js files and
3) modules are in xxx-module.js files

Related

How to properly configure requireJS

Hi I'm trying to make starting template for SPA project mainly using:
RequireJS, KnockoutJS, TypeScript, etc.
I'm having hard time figuring out how to configure paths and folder structure for RequireJS to work properly...
here is my folder structure:
Scripts
app
components
main.js
lib
knockout.js
jquery.js
here is my RequireJS config file:
var config = {
waitSeconds: 15,
paths: {
app: '../app',
'knockout': '/lib/knockout-3.4.2.',
sammy: '/lib/sammy-0.7.5.',
jquery: '../scripts/lib/jquery-1.10.2.'
}
};
This is my attempt for main.js:
define(['jquery', 'PageOne', 'PageTwo'], function ($, pageOne, pageTwo) {
$(document).ready(function () {
var app = Sammy('#main', function () {
this.get('#/pageOne', function () {
pageOne.activate();
});
this.get('#/pageTwo', function () {
pageTwo.activate();
});
});
app.run();
});
});
Here is my Index.cshtml script tag:
<script src="~/Scripts/lib/require.js" data-main="scripts/app/components/main"></script>
I saw in different project that config is called in header so this is in html header:
<script src="~/Scripts/app/config/require.config.js"></script>
My problem is that in main.js it looks for jquery under path defined in data-main (scripts/app/components/), but my jquery is in scripts/lib folder.
I'm trying to figure out by reading online the whole day but it's too much time for me I need someone to give me some hints how is this supposed to work?
Seriously having hard time figuring this out and RequireJS website just isn't helping me atm.
Note: I am beginner in JavaScript based projects, first SPA attempt,
never used RequireJS...
Your configuration file does not do anything. I'm assuming from your description that the script element that loads it is located before the script element that loads RequireJS. That's one valid way to configure RequireJS, but if you want RequireJS to pick up the configuration, you need to set the global variable require before you load RequireJS, and RequireJS will use the value of require as its configuration. Right now you are setting config, which is ignored by RequireJS. So:
var require = {
waitSeconds: 15,
// etc...
And once the configuration is in effect, you should be able to reduce your data-main to data-main="components/main".
I see some of your paths in the paths configuration end with a dot. That's most likely a mistake on your part, or you have some very strange file names.

Requirejs uses wrong path for asset in library

In a website I'm creating RequireJS is used as module loader. There is a "3d photo viewer" on this website and I'm using the Photo Sphere Viewer lib for these. One of the dependencies for this library is D.js. This is required in the library code as such:
... define(["three","D.js","uevent","doT"],b) ...
In my RequireJS configuration I defined a baseUrl and paths for the libs required by Photo Sphere Viewer libraries:
requirejs.config({
baseUrl: '/scripts',
paths: {
'vendor': 'lib/vendor',
'three': 'lib/vendor/three',
'uevent': 'lib/vendor/uEvent',
'doT': 'lib/vendor/dOT',
'D.js': 'lib/vendor/D'
}
});
photo-sphere-viewer is required by the website after a user requests to get a 3d photo. Code works a little like this:
requirejs(['main', 'deps', 'for', 'app'], function(a, b, c, d){
var showSphere = function(){
// loading logic and such
require('vendor/photos-sphere-viewer', function(PSV){
// do your 3d photo thing
});
};
var button = document.getElementById('button');
button.addEventListener('click', showSphere);
});
D.js is located at /scripts/lib/vendor/D.js. However when I test this, I get a 404 for /D.js. As if it is completely ignoring the baseUrl and path, but these aren't ignored for the other libraries, these get loaded normally.
I've added console.log(require.urlTo('D.js')) to the top of the Photo Sphere Viewer js file and somehow this logs the correct path: "/scripts/lib/vendor/D.js". However, one line further when D.js is actually required it seems to have 'changed its mind'. I've working on this for some time without result and I'm kinda considering just putting D.js in the website root, but of course that's not my preferred solution.
I think that the .js is throwing things off.
Change the config
requirejs.config({
baseUrl: '/scripts',
paths: {
'vendor': 'lib/vendor',
'three': 'lib/vendor/three',
'uevent': 'lib/vendor/uEvent',
'doT': 'lib/vendor/dOT',
'D_js': 'lib/vendor/D'
}
});
And call the define this way.
define(["three","D_js","uevent","doT"],b) ...
I suspect your problem is because of asynchronous loading of requireJs dependencies.
Since requireJs loads the dependencies asynchronously, the D.js file might not have been loaded yet when you are trying to use it.
If thats the problem, solution is to load the dependencies in a separate file before your require.js
<script type="text/javascript" src="/js/config.js"></script>
<script type="text/javascript" src="/js/require.js"></script>
See
Require JS is ignoring my config
and http://requirejs.org/docs/api.html#config

Path issue with RequireJS

I'm developing an applicattion with RequireJS and i have a module used as dependece. All dependences's libraries are in "lib/vendor", so, assumming it calls "MyModule", it is in "lib/vendor/MyModule/my.js.."
In my main.js i have:
3 requirejs.config({
4 paths: {
5 my: './vendor/MyModule/my',
....
And it works, but the problem is that "my.js" includes some files too
define(["./lib/a", "./lib/b"], function (a,b) {
....
});
These files "a.js" and "b.js" are inside of module's folder, so the structure should be something like this:
index.html
lib
main.js
vendor
MyModule
my.js
lib
a.js
b.js
The problem is when my.js invoked to "a.js" or "b.js" RequireJS tries to find them to "host.com/lib/lib/a.js" instead "host.com/lib/vendor/MyModule/lib/a.js"
According "http://requirejs.org/docs/api.html#defdep" the thing i'm doing it should work, but it is not happening
The problem is that relative dependencies are loaded relative to the name of your module rather than its path. You refer to this example:
//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
This will work only if the my/shirt.js file is loaded as the my/shirt module. In other words, there is an assumption in this example that there is no paths setting that will change the modules' paths.
Here is what happens with your code:
RequireJS loads main. You don't set a baseUrl so the baseUrl is set to /lib.
You require my. RequireJS resolves it to /lib/vendor/MyModule/my.js and loads it.
The my module requires ./lib/a and ./lib/b. When RequireJS resolves the relative paths, it uses the current module's name (my) as its starting point. The initial period in the two requirements means "get the directory part of the current module name and add the rest of the path to it." The directory part of my is the empty string, so the two paths become lib/a and lib/b and then are combined with the baseUrl to form /lib/lib/a and /lib/lib/b.
Note that the paths setting for my is not used at all in this computation.
One way to get around your issue would be to use map instead of paths. Whereas paths associates paths to module names, map associate module names to module names so:
map: {
'*': {
my: 'vendor/MyModule/my'
}
}
This tells RequireJS that in all modules (*) if the module with name my is required, the module with name vendor/MyModule/my is loaded.

How can I load multiple optimized requirejs modules dynamically in a production env?

I've started to play with require js on a dummy project. I now want to use the r.js script to build my project for production.
The context is this:
Main file called start.js is:
require([/* some stuff */], function (){ /* app logic */ });
which has an if that decides what I should require based on some condition.
The required files are either ModuleA or ModuleB
Both ModuleA and ModuleB have dependencies.
define([/*some deps*/], function(dep1, dep2...) {
/* app logic */
return { /* interface */
}
Everything works fine in development mode, before optimization and module concatenation.
When building with r.js I specify as module targets the following :
modules : [ { name : "start" }, { name : "ModuleA" }, { name : "ModuleB" } ]
The problem is that my ModuleA becomes :
define(dep1 ..);
define(dep2 ..);
define(ModuleA ..);
But nothings loads from ModuleA. The code from ModeulA in development loads and executes, the code after building loads but does not run.
How could I fix this problem?
UPDATE
http://pastebin.com/p1xUcY0A --> start.js
http://pastebin.com/dXa6PtpX --> ModuleA js-animation.js
http://pastebin.com/xcCvhLrT --> ModuleB css-animation.js no deps.
http://pastebin.com/j51V5kMt --> The r.js config file used when running the optimizer.
http://pastebin.com/UVkWjwe9 --> How the js-animation.js looks after running r.js. This is the file that has problems. I don't get the js-animation module from this file. The require does not return my js-animation object.
Edit:
After removing the .js at the end of the module definitions and in from start js, the optimized start.js is http://pastebin.com/LfaLkJaT and the js-animations module is http://pastebin.com/qwnpkCC6. In chrome, I get this error in my console http://pastebin.com/Hq7HGcmm
I believe the problem with your setup is that you end your module dependency names in .js. As per the docs:
RequireJS also assumes by default that all dependencies are scripts, so it does not expect to see a trailing ".js" suffix on module IDs. RequireJS will automatically add it when translating the module ID to a path.
If RequireJS sees a module name ending in .js it assumes that the module name is a path relative to the document. By ending your module dependency names in .js it works fine in development mode because RequireJS will go and load the file specified as a dependency. In your case it will load the file js/js-animation.js, see an anonymous define and load the module properly.
In production, your start.js module still requires "js/js-animation.js". RequireJS will load your optimized module at the path js/js-animation.js but now the optimizer has converted your anonymous modules into named modules (in this case "js/js-animation"). The result is the file will be loaded but no define'd modules within the file have a name that matches "js/js-animation.js" so in a sense your animation module is missing.
Solution / TL;DR: Remove the trailing .js from all your module dependency names (and your module definitions in the r.js config) and you should be fine. So your start.js should become (changes on line 4):
require([], function () {
var $html = $("html"),
animationModule = localStorage['cssanimations'] == 'true' ?
'js/css-animation' : 'js/js-animation',
$doc = $html.find("body");
console.debug("loading ", animationModule);
require([animationModule], function( animationModule ) {
animationModule.run({
target : $("div.flex")
});
} );
} );
Also note your may want to use baseUrl and paths in your RequireJS config to clean up module names (e.g. so you can remove the js/ prefix).
It seems this is problematic with the current require.js implementation. The way around it was to create a global mediator or mediator module and have all dynamically loaded modules call the mediator and announce themselves via an event. This worked for me.

Problem using Dojo build tool, 'could not load' error now occuring when trying to use compiled scripts

I was following along to this post by Rebecca Murphey: http://blog.rebeccamurphey.com/scaffolding-a-buildable-dojo-application
I was substituting her file structure with my own.
Running the normal version of the scripts works fine, but the moment I compile them using the build tool, the script errors.
It's very likely a small problem with how the files are referenced via my Profile.js script but maybe someone here can help me get the settings correct before running the build tool so the compiled files will work as they should.
My file structure is as follows...
/www
/Assets
/Scripts
/Classes
build.sh
Init.js
Load.js
Profile.js
/Dojo
Dojo.js
/dojo-sdk
index.html
My index.html file has the following code...
<script>
var djConfig = {
modulePaths : {
'Integralist' : '../Classes'
}
};
</script>
<script src="Assets/Scripts/Dojo/Dojo.js"></script>
<script>
dojo.require('Integralist.Init');
</script>
...and the Init.js file has the following code...
dojo.provide('Integralist.Init');
dojo.require('Integralist.Load');
dojo.declare('MyApp', null, {
constructor: function(config) {
this.version = config.version || '1.0';
this.author = config.author || 'Unknown';
}
});
var myapp = new MyApp({
author: 'Mark McDonnell'
});
alert(myapp.author);
alert(myapp.version);
...lastly, the Load.js file has nothing in it but this...
dojo.provide('Integralist.Load');
alert('I\'m the Load.js file');
...and this all runs fine. When I load index.html I get 3 alert messages, brilliant.
The problem occurs when I try to run the build tool.
Via Mac OSX i locate the /Classes/ directory and run 'sh build.sh' and the build.sh file within the /Classes/ directory consists of the following code...
cd ../../../dojo-sdk/util/buildscripts
./build.sh profileFile=../../../Assets/Scripts/Classes/Profile.js releaseDir=../../../Assets/Scripts/Release
...now, after running the build tool I have a new /Release/ directory created within my /Scripts/ directory, this /Release/ directory consists of...
/www
/Assets
/Scripts
/Release
/Integralist
/Classes
Init.js
Init.js.uncompressed.js
/dojo
--loads of dojo related files--
...I then created a separate index file called index-release-version.html and changed the script code as suggested by the article, so it looks like this...
<script src="Assets/Scripts/Release/Integralist/dojo/dojo.js"></script>
<script>
dojo.require('Integralist.Init');
</script>
...from here I get the following error...
Failed to load resource: the server responded with a status of 404 (Not Found)
Uncaught Error: Could not load 'Integralist.Init'; last tried '../Integralist/Init.js'
...and just for reference my Profile.js file that is used by the build tool consists of the following (and it's here I think the problem may be)...
dependencies = {
stripConsole : 'all',
action : 'clean,release',
optimize : 'shrinksafe',
releaseName : 'Integralist',
localeList : 'en-gb',
layers: [
{
name: "../Classes/Init.js",
resourceName : "Integralist.Init",
dependencies: [
"Integralist.Init"
]
}
],
prefixes: [
[ "Integralist", "../Classes" ]
]
}
Any help really appreciated as I desperately want to get my head around how Dojo works :-)
Thanks!
M.
I'd suggest working from the repo I linked to from my blog post (http://github.com/rmurphey/dojo-scaffold) -- I double-checked that it's definitely working :) -- and make changes to it until your changes break something, rather than trying to create your own structure right off the bat.
At a glance, I'm not 100% clear why you've got a Dojo.js file inside your directory structure, (is this the base Dojo lib or something else?), but the rest of Dojo is located elsewhere. If you use the structure I proposed, you can safely remove the djConfig declaration when using the built files, but as Dan mentioned, you may need to keep it if you're using a different configuration.
Do you have that djConfig variable in your index-release-version.html? It looks like Dojo is trying to find init.js at ../Integralist/Init.js, but you somehow need to tell it to look in ../Classes/Init.js
This is what your modulePaths : {'Integralist' : '../Classes'} was doing in your Index.html

Categories

Resources