about module in the angular - javascript

I am new in this field and reading about one project code. Here are two file.
https://github.com/PatrickO10/meetUp/tree/master/app/dashboard
In the first file:
(function(){
'use strict';
angular.module('app.dashboard', ['firebase']);
})();
In the second file, similiar code appears again
https://github.com/PatrickO10/meetUp/blob/master/app/dashboard/dashboard.controller.js#L4-L6
I see many code write like var app=angular.module(...), if you write in way of first file, how could you use the module again? and why you write it in this way?
I also want to know why you write the first file here, why don't you put all things in the second file.
Thanks.

When you define your module in angular, you have to define an array as second parameter with the list of modules your module depend on (or an empty array if is not depending on anything).
When you use your module in angular, you skip this second parameter.
These are the two cases in your code.
You could put everything in same file, but it is considered a general good practice to keep individual files for different controllers/services/directives (or even the definition of the module).

Related

Concatenating raw javascript to a webpack bundle

I'm currently working on a build process that uses webpack. One of the dependencies that I need to include in my bundle is an old third-party library that doesn't follow any module patterns. I wan't to just include it in it's raw form, but it's coded in such a way that the usual techniques don't work.
The offending library is coded a bit like this:
function OldLibrary() {
console.log('What are modules?');
};
var foo = window.OldLibrary;
// Proceeds to use foo without a care in the world
As you can see from the code above, the library assumes that it will always be in the global context, and so it doesn't bother to explicitly set window.OldLibrary.
At first I tried using script-loader, but this wraps the script inside function(module, exports) {}, which means that OldLibrary now belongs to the scope of that function instead of window's and this causes an exception. I also tried using imports loader like imports?this=>window, but this only sets this to window, so it doesn't have effect on functions that are supposed to be global.
Finally, I tried out raw-loader, but this just adds the script as a string, so it's not executed. Is there a way to tell Webpack to just concatenate the script as is without wrapping it inside another function?
Edit
It turns out that script-loader does actually handle this library as expected, I just wasn't matching it properly because it was the only file that didn't have a .min.js extension. I'm still interested in finding a way to concatenate scripts without wrapping them in functions, if possible.

How can I access constants in the lib/constants.js file in Meteor?

I followed the documentation to put the constants in the lib/constants.js file.
Question:
How to access these constants in my client side html and js files?
Variables in Meteor are file-scoped.
Normally a var myVar would go in the global Node context, however in Meteor it stays enclosed in the file (which makes it really useful to write more transparent code). What happens is that Meteor will wrap all files in an IIFE, scoping the variables in that function and thus effectively in the file.
To define a global variable, simply remove the var/let/const keyword and Meteor will take care to export it. You have to create functions through the same mechanism (myFunc = function myFunc() {} or myFunc = () => {}). This export will either be client-side if the code is in the client directory, or server-side if it is in the server directory, or both if it is in some other not-so-special directories.
Don't forget to follow these rules:
HTML template files are always loaded before everything else
Files beginning with main. are loaded last
Files inside any lib/ directory are loaded next
Files with deeper paths are loaded next
Files are then loaded in alphabetical order of the entire path
Now you may run into an issue server-side if you try to access this global variable immediately, but Meteor hasn't yet instantiated it because it hasn't run over the file defining the variable. So you have to fight with files and folder names, or maybe try to trick Meteor.startup() (good luck with that). This means less readable, fragile location-dependant code. One of your colleague moves a file and your application breaks.
Or maybe you just don't want to have to go back to the documentation each time you add a file to run a five-step process to know where to place this file and how to name it.
There is two solutions to this problem as of Meteor 1.3:
1. ES6 modules
Meteor 1.3 (currently in beta) allows you to use modules in your application by using the modules package (meteor add modules or api.use('modules')).
Modules go a long way, here is a simple example taken directly from the link above:
File: a.js (loaded first with traditional load order rules):
import {bThing} from './b.js';
// bThing is now usable here
File: b.js (loaded second with traditional load order rules):
export const bThing = 'my constant';
Meteor 1.3 will take care of loading the b.js file before a.js since it's been explicitly told so.
2. Packages
The last option to declare global variables is to create a package.
meteor create --package global_constants
Each variable declared without the var keyword is exported to the whole package. It means that you can create your variables in their own files, finely grain the load order with api.addFiles, control if they should go to the client, the server, or both. It also allows you to api.use these variables in other packages.
This means clear, reusable code. Do you want to add a constant? Either do it in one of the already created file or create one and api.addFiles it.
You can read more about package management in the doc.
Here's a quote from "Structuring your application":
This [using packages] is the ultimate in code separation, modularity, and reusability. If you put the code for each feature in a separate package, the code for one feature won't be able to access the code for the other feature except through exports, making every dependency explicit. This also allows for the easiest independent testing of features. You can also publish the packages and use them in multiple apps with meteor add.
It's amazing to combine the two approaches with Meteor 1.3. Modules are way easier and lighter to write than packages since using them is one export line and as many imports as needed rather than the whole package creation procedure, but not as dumb-error-proof (forgot to write the import line at top of file) as packages.
A good bet would be to use modules first, then switch to a package as soon as they're tiring to write or if an error happened because of it (miswritten the import, ...).
Just make sure to avoid relying on traditional load order if you're doing anything bigger than a POC.
You will need to make them global variables in order for other files to see them.
JavaScript
/lib/constants.js
THE_ANSWER = 42; // note the lack of var
/client/some-other-file.js
console.log(THE_ANSWER);
CoffeeScript
/lib/constants.coffee
#THE_ANSWER = 42
/client/some-other-file.coffee
console.log THE_ANSWER

Module pattern defined in separate files

Is there a convenient approach to code organization, which allows to create a module pattern, but define its internally exposed functionality in separate files.
So, with a module below, can SomeInternalObject2 be defined in another js file and still be accessible from the first file (assuming proper ordering of script files)?
var MyModule = (function(){
function SomeInternalObject1(){..}
function SomeInternalObject2(){..}
return {
this.publicFunction = function(){..}
}
})();
EDIT: Perhaps I'm thinking about it in a wrong way. Code organization is a development-time concern. Require.js, module-loading, etc.. is a run-time concern.
Have look at jTable (javascript). The author augments the main object from different files. It is not exactly what you are asking for, but the intention or goal seems similar. I might add code later.

How do I instantiate require.js modules on different pages, partials with codeigniter?

I'm trying to update the javascript on a large scale, php/codeigniter based website. It has many, many php partials for code being loaded onto certain pages, but only one footer, header. Most of the partials have inline script tags in them for loading javascript. This needs to be fixed and because the site is very modular with components being used multiple times across pages, require.js seems like a pretty good solution.
So, it's instantiate javascript, we typically do this.
<script type="javascript" src="../js/scriptname.js">
<script type="javascript">
DP.scriptname.init(parameters)
</script>
I'd like to get away from this and just have a have a single entry point for the js using require.
My question is this: what's the best way to instantiate javascript for certain pages using require? Do I need I need to continue including my scripts in the partial and then do something like writing a require module for that specific page and then wrap it all in my data-main script like this? We're planning on using Backbone and Marionette as well, but I won't be able to use the Backbone router to do anything like setting hash URLs. Should I use the URLs to instantiate my require modules perhaps?
Ok, hope someone can help. My experience has typically been in building single page websites. This is different. Thanks
Cam
Well, if I understand your question correctly, you can use Require JS in such way.
First of all, write a config in which you can describe mapping between module names and concrete files. For example:
requirejs.config({
baseUrl: 'js/modules' // by default load any module using this path
});
After that you should refactor your existing module and adjust it to the AMD format (see http://requirejs.org/docs/whyamd.html)
As a result of this step you will have something like this (let's say in file 'js/modules/scriptname.js'):
// module has the same name as the file, which contains it - "scriptname"
define(function () {
// define the module value by returning a value
return function () {};
});
And as a final step you can refactor your inline script and use this module in such way:
<script type="javascript">
// when we place name of the module as a first argument of the "define"
// function, Require JS find file that contains it and load it asynchronously
define(["scriptname"], function (scriptname) {
// "scriptname" now contains value that we recieve from the module definition
scriptname.init(parameters);
});
</script>
Hope this helps.
Note. My solution based on this section of official Require JS documentation: http://requirejs.org/docs/api.html#jsfiles
This question seems to come up a lot, so I'll point you to some resources that may help:
How does RequireJS work with multiple pages and partial views? - https://stackoverflow.com/a/10816983/617615
Modular HTML components with RequireJS - http://simonsmith.io/modular-html-components-with-requirejs/
Example RequireJS-based project that has multiple pages that share a common set of modules - https://github.com/requirejs/example-multipage

AngularJS module dependencies - how many times can I list them?

I scaffolded a simple Angular app using Yeoman, and I've been playing with it ever since.
Inside the file app.js, which is the first one listed as a <script> inside index.html, I define the main module as:
angular.module('myMod', [])
.config(...)
Note the empty array of dependencies.
Now, when I want to, say, add a filter to this module, I create a myFilter.js file (which I load after app.js inside index.html); myFilter.js consists of:
angular.module('myMod').filter(...)
Note there's just one parameter to the module() function. If I pass the empty array of dependencies as a parameter to this module() function, really nothing appears on screen.
I've been playing with a bunch of other files which extended myMod with controllers, and passing [] as a parameter to the angular.module() function breaks my app every time.
It seems to me like I can only call angular.module() once using the second parameter, which may have some sense (how many times do I want to list my dependencies? What about consistency?). Is it that way?
If it is, is there some standard place where to list dependencies for a module?
angular.module("myModule",["dependencyA"]) will create a new module (this will crash if module allready exists.)
angular.module("myModule") uses an already known module.
This will also affect how you need to load the scripts in the index.html
You should declare your dependencies only once. In addition, it's best practice to keep all of your filters as a separate module that your app depends on, for example:
var myApp = angular.module('myApp', ['myApp.filters', 'myApp.directives', 'myApp.someOtherDependency']);
then, you would define your filters as a module that your app is dependant on:
angular.module('myApp.filters', []).filter(...)

Categories