Addon not working - ember.js

I have an Ember Addon which I've put up at Github here:
https://github.com/lifegadget/ember-dictionary
It passes all its unit tests and in a non addon form it is working fine in one of my projects but I'd like to lift it out the project and be able to use it as an addon. Still I'm clearly missing a step in how to expose the two Ember classes. This can be seen in the dummy app which tries to create a very simple model like so:
import DS from 'ember-data';
import DictionaryModel from 'ember-dictionary';
export default DictionaryModel.extend({
foo: DS.attr('string')
});
Then when the route (tests/dummy/routes/index.js) tries to use the model I get the following error:
Error while processing route: index Cannot read property 'extend' of undefined TypeError: Cannot read property 'extend' of undefined
To me this feels like a ES6/namespacing issue but I'm not sure how to overcome it. I did try the following more explicit import statement:
import DictionaryModel from 'ember-dictionary/models/dictionary-model';
but the same error occurred. Any help would be greatly appreciated.

I have bumped into enough walls that I think I can at least partially answer my question but some questions still remain so I won't mark this answer correct with the hope that others may post a more complete answer.
The first distinction I realised I hadn't been making clear enough for myself was whether to target the Ember App's namespace or to target an independent namespace for the addon. Classes defined in the app directory of the addon will be available to any application which uses the Addon in it's own namespace. In contrast, classes in the addon directory will be namespaced to the addon's namespace.
I have seen a lot people define classes in the addon's app directory and then proxy it through to the addon directory with something like:
// addon/mixins/dictionary.js
import DictionaryMixin from 'ember-dictionary/mixins/dictionary';
export default DictionaryMixin;
Although I've seen this I am still having problems getting these external namespaced classes to work. I think there may be another step needed to add a index.js entry point for the addon and then export these classes there. In any event, I'll leave this area alone as I decided to get the internal namespaced solution working first.
My next problem in the internal namespaced solution was centered around the dummy application that gets built as part of the addon creation process. I wanted this dummy application to have a model which would use the Mixin I created in the addon and I thought I'd be able to refer to it as:
import DictionaryMixin from 'ember-dictionary/mixins/dictionary';
but this couldn't be resolved by the Dummy test application so I had to resort to:
import DictionaryMixin from '../mixins/dictionary';
Which I guess is appropriate considering that my "external namespaced solution" isn't working yet ... falling back to the internally namespaced solution was required.

Related

Ember v. 2.x: watch vendor folder

I'm developing an Ember-JS application with a lot of JavaScript that performs of all kind of UX and styling tasks.
Because these tasks fall out of the scope the MVC-logic, I've put them into modules that I put in the vendor map.
Putting them into the Vendor folder doesn't mean I'm done tweaking these files, but to test them, I'm required to re-start the ember-server over and over again.
How can I make Ember watch these JS-files in my vendor folder and re-compile them when I change them?
The following page answers for Ember v. 1, but doesn't apply to Ember 2.0: https://discuss.emberjs.com/t/solved-watch-addon-directory-for-changes/6410/4
I also tried creating an addon, but ember (cli) answers with: “You cannot use the addon command inside an ember-cli project.”
It took me a while to connect all the pieces of information scattered over internet, but using #Lux 's anwers, this is what I found out.
1) Using the ember-cli, I generate a 'utility' (hence the utils folder):
ember g util grid-layout
This gives you a JS-file “app/utils/grid-layout.js” template to fill in. In my case, it was a matter of…
2) copy-paste the body of the function I created earlier, into the body of the function that ember-cli came up with:
export default function gridLayout(tree) {
…
return tree
}
3) Importing the function in the controller, in my case controllers/index.js. I found different examples on how to do this, with and without curly braces and using different paths to the module file, but this is what made it work for me:
import Ember from "ember";
import gridLayout from "../utils/grid-layout";
export default Ember.Controller.extend({…
Links:
https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Statements/export
https://blog.abuiles.com/blog/2014/10/03/working-with-javascript-plugins-in-ember-cli/
In ember-cli version 2.11.0 by default its watching vendor foler.
https://github.com/ember-cli/ember-cli/pull/6436

How to use custom "abstract" route in emberjs

I have started with ember and ember-cli. Ember-cli is somewhat different than Ember shown in most of the tutorials.
I can not understand what do I need to do to inherit my own custom "Route".
For example I made a file:
authenticated.coffee
and in it:
AuthenticatedRoute = Ember.Route.extend
Now I want to do the following:
make a new file called secret.coffee with:
SacretRoute = AuthenticatedRoute.extend
The best I got so far is import AuthenticatedRoute from '../routes/authenticated' which says that it included the file but says that it can not do .extend on undefined.
I do not quite understand it and I have googled all around so please if there is an answer somewhere please you can politely give me a link.
Thank you.
I am not familiar with coffee script but have you may have forgotten to export AuthenticaedRoute.
And also suggestion from stefanpenner who is creator of ember-cli. Don't hold reference of your extended route or controller just export it as
export default Ember.Route.extend();

Qunit testing an ember controller, located in a file that contains multiple controllers?

So, I've been trying to qunit test an Ember controller, The problem is, The controller is inside a coffeeScript file, that contains multiple controllers.
Now, The ember testing guide says, In order to test a controller, I should use the 'moduleFor' helper like so:
moduleFor(fullName [, description [, callbacks]])
In my case, the full name is say: "CustomersIndexController" , But because it's included in "customers_controller.coffee" that in it self includes multiple controller, Testing it became problematic .
After an Endless digging online, I found out (Please correct me if I'm wrong) that the resolver cares only about the file name, not about the name that 'export default myModel' provides
To make it more clear, Here is my "customers_controller.coffee" :
`export { CustomersIndexController, CustomersItemController }`
CustomersIndexController = Ember.ArrayController.extend
#Code goes here ......
CustomerItemController = Ember.ObjectController.extend
#Code goes here .....
And here is the customers-controller-test.coffee file :
`import { test, moduleFor } from 'ember-qunit';`
moduleFor("controller:customers-index-controller", 'C Controller')
test "it's an App.Controller", -> ok(#subject())
I've tried all the ideas that my brain could produce...without any luck(changing the controller name from camelCase to dasherized, to absolute path, even tried importing customers_controller.coffee), But I keep getting:
Setup failed on it's a App.Controller: Attempting to register an unknown factory: `controller:customers-index-controller`
Any Help/Advice/Links are highly appreciated.
You should be able to defined it in lower camelCase.
moduleFor('controller:postsIndex', 'Posts Index Controller');
http://jsbin.com/ruhalota/1/edit
If you take a look at the documentation for the resolver with ember-cli, you'll see that it does indeed only care about the names of the files, and what is the default export of them: http://www.ember-cli.com/#using-modules
In your case, you'll need to split your controllers into multiple files, so the resolver can find and instantiate them properly. So, the two files would be:
app/controllers/customers/index.coffee
app/controllers/customers/item.coffee
This is all assuming you are using ember-cli. If you are still using ember-app-kit, you might need to adjust this slightly, but the same basic idea should apply.

ember app kit: some testing functions not defined

Building my first ember app based on ember app kit.
I wanted to test the current route after transition - and found just what I need in ember docs - currentRouteName, currentURL and currentPath helper functions.
However, if I use these functions i get a "ReferencError: currentRouteName is not defined".
I stumbled upon this pull request that I suppose has the initial implementation of the same thing - but was closed in favor of adding this functionality to ember proper... For the time being, I copied the code from this PR and it does indeed get picked up and pass my tests.
Question: how can I utilize all the functions defined in my copy of ember.js in testing?
These route helper functions are defined alongside with visit and click functions, which my tests seem to pick up without issue. Or, are my tests picking these functions up from somewhere else?
Those methods weren't added as global helpers until 1.5, so they are only available in the canary builds as of writing this.
http://emberjs.jsbin.com/wipo/2/edit

Lazy Loaded Ember Application

I am typically searching for answers here but I finlly gotten to the point where I can't find a good answer.
I am looking to build an ember app which only initially loads in the things that it needs just to start and open the main route. All other controllers, views, templates, etc. Would be loaded lazily when a specific route gets triggered.
I have found a good example of how to accomplIsh this here:
http://madhatted.com/2013/6/29/lazy-loading-with-ember
My main question is to determine what build tools out there support this theory of lazy loading application code? So far, I've seen that Brunch, Yeoman, and Ember App Kit seemed to minify and concatenate all the scripts and templates. I am very happy with minification but need those files separate. I have thought about just putting this code into the app/assets location so that it gets copied over without concat but it does not get minified.
Does anyone have a solution? Thanks!
You can do this with brunch by adding the following to your brunch config
files: {
javascripts: {
joinTo: {
'javascripts/app.js': /^app(\/|\\)(?!admin)/, // concat everything in app, except /app/admin
'javascripts/vendor.js': /^vendor/,
'javascripts/admin.js': /^app(\/|\\)admin/ // concat only /app/admin
}
}
}
Grunt (used in yeoman and ember app kit) is ridiculously flexible, so I'm sure you can set up the same thing there by diving into Gruntfile.js
The question was: "I am looking to build an ember app which only initially loads in the things that it needs just to start and open the main route. All other controllers, views, templates, etc. Would be loaded lazily when a specific route gets triggered.".
Ember expects to have anything it needs right there when the page gets loaded. I wouldn't be wrong, but lazy loading of routes doesn't seem to be a feature of Ember. Ember CLI is the same. It uses bundling and minification to reduce the overload. But everything should be there to make it work.
Instead, people like me would like to load things only when they are required.
When you try to implement lazy loading in Ember, everything should be represented by a module (file.js): a route, a module; a controller, a module; and so on.
You should follow a schema (like POD), to which apply a mechanism to find things where they are supposed to be.
Every module should know its dependencies. But some of them are very frequent (route, controller, template).
You should use a module loader for the browser. It can be requirejs or whatever you like. But ES6 is at the door. Let's think about that.
Many people use beforeModel hook to achieve a result. I did it, and it works, if you don't use link-to component. Otherwise everything crashes. Why? Because of href computed property. When a link-to has been inserted, an href is calculated for it. Because of that, Ember looks for the route where the link points to. If the route doesn't exist, one is created from route:basic.
A solution could be the preloading of all the routes represented by all link-tos inserted in the page. Too much expensive!
An integration to this answer can be found at Lazy loading route definitions in Ember.js
For an initial solution to lazy loading of routes organized in POD, have a look at https://github.com/ricottatosta/ember-wiz. It is an ES6 based approach, which relay on SystemJS as module loader.