I am an Ember noob and am trying to get it to work; however I am confused about the App.initialize() method.
It throws errors (it can't find the object App) if I use the following code:
App = Ember.Application.extend()
App.initialize()
However if I use the following code; it says initialize is being called twice.
App = Ember.Application.create()
App.initialize()
What is the best way to do this?
The Application no longer provides the initialize method. Instead you should use Application#deferReadiness and Application#advanceReadiness combined.
Example extracted from Ember's source code:
App = Em.Application.create();
App.deferReadiness();
jQuery.getJSON("/auth-token", function(token) {
App.token = token;
App.advanceReadiness();
});
Additionally, check the sample in jsfiddle:
window.App = Em.Application.create();
App.deferReadiness();
window.setTimeout(function() {
Em.TEMPLATES["application"] = Em.Handlebars.compile('<h1>App</h1> this is a template');
App.advanceReadiness();
}, 1500);
First, You have to understand the difference between create() and extend(). Easy way to understand is extend() method just extends the class of Ember.Application but create() method creates the instance of Ember.Application(). While creating the instance it runs the constructor. There are 3 ways to create the Ember.App and run it.
1
var App= Ember.Application.extend()
App.initialize()
2.
var App = Ember.Application.create()
This initialises as soon as u create object.
3
var App= Ember.Application.extend()
App.create()
To understand Ember Objects more go through this link. Understanding Ember.Object
Just create your application and let Ember initialize it.
All you need to do is:
App = Ember.Application.create()
The App will not be initialized immediately. It waits, at least, for DOM readiness and for the rest of your classes to be defined (by waiting until control is returned to the browser from the currently executed JavaScript).
If you want to defer it for other reasons, do something like this:
App.deferReadiness();
$.getJSON("/boot", function() { App.advanceReadiness(); });
This will wait to boot the app until the /boot Ajax call returns.
Just have a look here how to do this stuff:
http://emberjs.com/documentation/#toc_creating-a-namespace
How to bootstrap:
window.App = Ember.Application.create();
Without ever using ember.js, I would suggest that create and initialize both do initialization, that's why you get the latter error telling you it's inited twice.
And your first version is trying to extend the Application object, that is you create new functionality.
Ember "create" method accepts either no arguments, or an object containing values to initialize the newly instantiated object with, so you might also go like this below:
var appConfig = {
Token: token;
};
App = Ember.Application.create(appConfig);
Related
Sorry if this is a dumb question but I'm new to JavaScript/Node.js. This code below eludes me and I've done a fair bit of research... My questions below are more specifically related to instantiation.
I don't understand this:
var myApp = require('express');
var myCode = myApp();
How I see that it should be for instantiation:
var myApp = new Express();
var myCode = myApp.insideExpress();
How anonymous function expressions are:
var myApp = function();
var myCode = myApp();
If the word "require" acts as a sort of anonymous function expression, then how are things instantiated in the background? This is very important for making proper patterns, no?
My questions are:
What's happening in the background for the first example, is JavaScript/Node.js instantiating/constructing or not at all?
Are people who do this just creating bad patterns? Why should I use this pattern?
If no instantiation, then why not?
Thanks in advance
const myVar = require("someModule") loads a module from the file system, runs the module initialization code and assigns the module exports to your variable. The module loading sub-system maintains a cache so if it was previously loaded, it is not loaded or run again, the module's exports are just retrieved from the cache and assigned to your variable.
So, when you do this:
var myApp = require('express'); // load express module, assigns exports to myApp
var myCode = myApp(); // calls myApp() function and assigns result to myCode
The first line loads the express module and assigns the exports from that module to your myApp variable. In this particular case (it varies from module to module), the exports from the Express module is a function. So, after that first line of code, myApp contains a function which happens to be a factory function for creating new Express app objects.
The second line of code calls that factory function which returns a new Express app object.
A module can export anything it wants. In the case above, it exported a function, but it's also common to export an object that has a whole bunch of properties which you can then access. You can also export a constructor in which case the caller would then use new with the constructor to create a new object from it.
In the Express module, it did not export a constructor (which is why you don't use new with it). Instead, it decided to export a factory function that, when called, creates and returns a new object. This is just a design decision that can go either way depending upon the needs of the module and the whims of the code writer.
I can't really tell what you're asking here with this code:
var myApp = new Express(); // the express module does not export a constructor
var myCode = myApp.insideExpress();
This would work only if Express was a constructor function. The express module itself does not choose to export a constructor function so this is not how you use the express module. It could have been designed this way, but it was not. They simply made a different design decision when designing it.
For this other case you show:
var myApp = function();
var myCode = myApp();
That first line of code doesn't make any sense. Perhaps you meant for it to have a body to the function:
var myApp = function() { some code here };
var myCode = myApp();
In that case, myApp is being assigned a function expression (which is just one of several ways to declare a function). It's similar, though not exactly the same as:
function myApp() { some code here }
If the word "require" acts as a sort of anonymous function expression, then how are things instantiated in the background? This is very important for making proper patterns, no?
require('someModule) loads a module and returns the exports from the module which can be any Javascript data type. It doesn't act as an anonymous function in any way. require() is an actual function and you are just calling it and getting back its return value. Remember that in Javascript, you can return any data type from a function, include return another function (which is what the express module does).
What's happening in the background for the first example, is JavaScript/Node.js instantiating/constructing or not at all?
No instantiating or constructing. It's just loading a module, running its initialization code and return its exports. Some objects are created by the module loading system that are used for its own housekeeping, but the module itself is just initializing itself and then deciding what it wants to export.
Are people who do this just creating bad patterns? Why should I use this pattern?
Modules are highly useful in node.js development and it is considered good design to use proper module design. There are many, many advantages to good module design such as easier code maintenance, easier code testing, easier code reuse, easier code sharing, no need to create globals in order to share code, etc...
If no instantiation, then why not?
A module decides what it wants to export. It can, in its initialization code, create an instance of an object and export it. It can export a factory function that creates an instance of an object when called. It can export a constructor directly that lets the caller use new with it to create an instance of an object. It can export a utility function that just carries out some function and doesn't create any objects. It can export just data. It can export a plain object with multiple properties on it that have all sorts of possible uses. The possibilities are endless and it entirely depends upon what the purpose is of the module and what it wishes to share with the other module that loaded it.
It's just loading a library or a module into your script. It is not instantiating a new object. It's just making the loaded module's functions etc available to your current script. Here is a good writeup that I found,
http://fredkschott.com/post/2014/06/require-and-the-module-system/
I hope that helps answer your question.
I have outerView and innerView inside my require.js module. They can be described with few statements:
InnerViews is instantiated on OuterView rendering
InnerView calls calculated method on own instantiation
InnerView.calculate method use AJAX, which is undesirable in unit tests (with jasmine)
I need: in my jasmine tests replace innerView.calculate method call with direct call to innerView.handleResults with hardcoded data argument.
Problem: The problem is also that in tests I have access only to outerView. So I need to replace innerView.calculate method definition before the innerView is instantiated.
Question: How to replace innerView.calculated method definition before innerView is instantiated?
Code:
define(".....", function(...) {
var innerView = Backbone.View.extend ({
initialize: function() {
......
calculate(opitons);
},
//I NEED TO REPLACE THIS WITH handleResults(hardcodedData)
calculate: function(options) {
var $this = this;
Utils.doSmth(options).then(
$this.handleResults
);
},
handleResults: function(data) {
....
}
});
var outerView = Backbone.View.extend ({
subViews: [],
render: function() {
subViews[0] = new innerView();
}
});
return outerView;
}
Keep in mind that the BDD philosophy is to test behavior. Ask yourself, do you really want to change how your functions work in your unit tests? By providing an alternate code path, you aren't testing the actual behavior you'll see in production.
For example, what if in your then function you do more complex data massaging than simply calling handleResults(...)? You then need to bring knowledge of this logic into your unit tests so you can mock out the rest of the chain correctly.
It sounds to me like what you really need is a way of mocking the AJAX request, not a way of changing how your code works. There are several ways to accomplish this. Two of the most popular are:
jasmine-ajax -- jasmine-specific
Sinon.JS -- standalone framework for creating spies, mocks, and mock HTTP servers.
I have used Sinon.JS quite a lot for testing XHR-related code paths to great effect.
That looks like a design problem to me. You have a hard-coded dependency on the innerView type in your outerView, and you are hiding it inside a closure (aka module). Worse, that inner, hard-coded dependency is hooked up to the rest of the universe (AJAX call). You'll have to expose the inner view somehow in order to make it testable.
It seems to me that at the very least, you have to open up your outerView like this:
var outerView = Backbone.View.extend ({
subViews: [],
initialize: function (options) {
this.innerView = innerView;
}
render: function() {
subViews[0] = new this.innerView();
}
});
That way, you can at least modify outerview.innerView in your tests before you call render.
And at that point, it is only a small additional step to actually inject the dependency in initialize, perhaps with a default (this.innerView = options && options.innerView || innerView;), if you ever feel the need.
My case is that I need to require a module named Router in my index file meanwhile assign value to a variable of the module.
I have figured out several ways to achieve it. However, as a beginner, I want to know which one is the best practice or design and why cannot use the others.
Method 1 - export a setter & keep variable as 'private'
router.js
var handler;
exports.setHandler=function(h){handler=h};
exports.route=function(){console.log(handler)}
index.js
var router=require('./router');
router.setHanlder('test');
router.route();
Method 2 - let variable be 'public' and use 'this' to refer
router.js
exports.handler={}; //not necessary
exports.route=function(){console.log(this.handler)}
index.js
var router=require('./router');
router.hanlder='test';
router.route();
Method 3 - export a factory function to receive value as a parameter
router.js
module.exports=function(handler){
return {route:function(){console.log(return handler)}};
}
index.js
var router=require('./router')('test');
router.route();
Which one above should I use? Any other methods suggested?
I would suggest method 3, it being a callback;non-blocking code. Also, it is close to what seems natural to me!
I like to do it this way - I recommend trying to stay away from handlers like that with modules because it is a complexity trap that will catch you one day, that is, unless you need them =).
module.exports = function( options ) {
// set options
// based on options set vars and functions on this
if (options.test === true) this.route = function() {//....}
else this.route = function() {//......}
}
then in the using file
var Router = require('router.js');
var router = new Router({/* options */});
router.route();
It's possible to use method 2 as well. If you are using aws lambda, you will see that they used method 2 to export the function handler.
I'm novice in jasmine and I need to write some unit tests for node.js app in this framework.
I have some problems, one of them is this described below:
var sampleFunction = function(){
var loader = new Loader(params);
// rest of logic here
}
I want to write unit test for sampleFunction. To do this I need to create spy on Loader constructor and check what this constructor gets as params and what kind of object is it returning.
Any ideas how to do that? I tried to create spy on Loader.prototype.constructor but it wasn't a solution to this problem.
OK, so normally in client-side JavaScript you would use the window object like so jasmine.spyOn(window, 'Loader')
In node, however, there is no window object and despite claims to the contrary global is not a substitute (unless you are in the REPL which runs in global scope).
function MyConstructor () {}
console.log(global.MyConstructor); --> undefined
console.log(this.MyConstructor); --> undefined
So, in node you need to attach your constructor to an object. So just do something like this
var Helpers = {
Loader: Loader
};
var constSpy = jasmine.spyOn(Helpers, 'Loader').andCallThrough();
sampleFunction();
expect(constSpy).toHaveBeenCalled();
The andCallThrough call is only necessary if you want your constructor to do something (often with constructor you do).
This is a little hacky, but it works and seems to be the only way to achieve this through jasmine's implementation within node.
I am writing a web application which uses YUI3 for all it's JS needs. I need functionality such as Tooltips, Tooltips whose content is determined by AJAX queries, Toggle Buttons and so on.
I was not sure who to build an architecture to achieve all this. I have taken the following approach
var Myapp = function(){
this.toggleButton(node,config)
{
YUI().use(....,function(Y){
//code to convert NODE into a toggle button;
});
}
return this;
};
In my application I then just convert all the buttons into toggle buttons by calling
var app = Myapp();
app.toggleButton(Y.all('.toggle-buttons'),{'text1':'TOGGLE_ME','text2':'TOGGLED_ME'});
All this works. But I wanted to know from more experienced developers if there is anything fundamentally wrong with this approach.
Is this a good way to use JavaScript ?
return this;
This is unneccesary since function constructors return this by default.
var app = Myapp();
You forgot to call new Myapp() without the new keyword this will be the window object and you are effectively writing to global scope.
There's a fundamental problem in your code:
var MyApp = function(){
this.toggleButton(node,config)
{
...
You're not defining a function for MyApp. Instead, you try to invoke toggleButton each time you instantiate it. It should fail because the function is undefined
In your case, Class definition and instantiation is not needed because MyApp is being used as a utility.
You can define MyApp as a static Object:
var MyApp = {
toggleButton: function toggleButton() {
// your code
}
};
And you can use it anywhere by:
MyApp.toggleButton();