BaseURL in Ember CLI application with IE9 support - ember.js

For my Ember CLI application I want to use a baseURL, as described here. It works very well for the History API, but for the old Hash API it won't work as expected.
My configuration:
module.exports = function(environment) {
var ENV = {
environment: environment,
baseURL: '/base/',
locationType: 'auto',
...
};
...
return ENV;
}
In IE9 i got localhost:4200/#/base/login instead of localhost:4200/base#/login. Going manually to this page results in a blank (white) page.

I found you have to set the router rootUrl as well as the environment baseUrl.
//router.js
import Ember from 'ember';
import config from './config/environment';
let Router = Ember.Router.extend({
location: config.locationType,
rootURL: config.baseURL
});
export default Router;

It's a known issue apparently: http://github.com/stefanpenner/ember-cli/issues/417

Related

The proper way to store/load statics in Ember App

currently I'm thinking of the way to load statics into my Ember app.
The problem:
I have app branded logo, app name, app title (browser tab label), texts for routes etc.
What I'm doing now is the following:
model() {
let defaultHeaderModel = {
logo: '/img/logo-cloud.svg',
brand: {
name: 'CloudCenter',
logo: '/img/logo-cloud.svg'
},
userLinks: [{
text: 'Logout',
route: 'logout'
}],
navigation: [{
text: 'Login',
route: 'login'
}]
};
}
As you can see all of the values are hardcoded. What I'd like to do is to somehow load that "statics" and use them through some variables. For ex: header.logo = resources.logo.
My thoughts:
1) Use environment - store all of that values in the config.js and import it where needed. Cons: not sure if that data belongs to environment
2) ES6 POJO which can be imported to the app.
3) .json and some staticsService which will load .json file and through it I will have access to that values.
Are there any standardized approach to do such things? Or maybe better suggestions?
You can create service, and have method(loadData) which will return Promise and will be resolved with your JSON data and update property in service. You need to call loadData in beforeModel hook, after the all the promises resolved only then it will move to model hook.
Refer twiddle basic demonstration
services/my-service.js
import Ember from 'ember';
export default Ember.Service.extend({
defaultHeaderModel:{},
loadData(){
var myServiceDataLoadPromise = Ember.RSVP.Promise.resolve({one:1});
myServiceDataLoadPromise.then(result =>{
this.set('defaultHeaderModel',result);
});
return myServiceDataLoadPromise;
}
});
routes/application.js
inside beforeModel hook, you can load service with data, it can be done any of the route which requires data.
import Ember from 'ember';
export default Ember.Route.extend({
myService: Ember.inject.service(),
beforeModel()
{
return Ember.RSVP.all([this.get('myService').loadData()]);
}
});
controllers/application.js
import Ember from 'ember';
export default Ember.Controller.extend({
myService: Ember.inject.service(),
appName: 'Ember Twiddle'
});
templates/application.hbs
{{myService.defaultHeaderModel.one}}

Torii Configuration is not being loaded in ember cli

I'm having a lot of trouble getting ember simple auth with torii working at all at the moment using Ember CLI.
After creating a new Ember CLI app and installing torii, ember-cli-simple-auth and ember-cli-simple-auth-torii, I have a couple of buttons on my login page
Here is the contents of my routes/login.js:
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
googleLogin: function() {
this.get('session').authenticate('simple-auth-authenticator:torii', 'google-oauth2');
return;
},
facebookLogin: function() {
this.get('session').authenticate('simple-auth-authenticator:torii', 'facebook-oauth2');
return;
}
}
});
The relevant part of my environment.js file is:
var ENV = {
...
torii: {
providers: {
'google-oauth2': {
apiKey: 'api-key-here',
scope: 'profile',
redirectUri: 'http://localhost:4200'
},
'facebook-oauth2': {
apiKey: 'api-key-here',
redirectUri: 'http://localhost:4200'
}
}
},
...
};
When I hit the actions in my login.js, I get the following error:
Error: Expected configuration value providers.facebook-oauth2.apiKey to be defined!
or
Error: Expected configuration value providers.google-oauth2.apiKey to be defined!
Why is torii not picking up my environment.js configuration?
You need to create the app in facebook and google, get the api key and place it where it says:
apiKey: 'api-key-here'
in your environment.js
Turns out my problem was a simple one, the ember serve process needed to be restarted (Ctrl + c, and then re run ember serve).

How to do dependency injection in Ember with Ember CLI?

First, I made a small Ember app without Ember CLI.
I had this piece of code.
window.MyApp = Ember.Application.create({
ready: function() {
this.register('session:current', MyApp.SessionController, { singleton: true });
this.inject('controller', 'session', 'session:current');
}
});
This worked.
Then I decided to rewrite everything from scratch with Ember CLI.
I edited the file app/app.js and added the ready hook just like in my previous version.
var App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver: Resolver,
ready: function() {
this.register('session:current', App.SessionController, { singleton: true });
this.inject('controller', 'session', 'session:current');
}
});
This doesn't work.
The session controller does exist. That's the content of the file app/controllers/session.js
export default Ember.Controller.extend({
isLoggedIn: false,
});
The error message I get is
TypeError: Attempting to register an unknown factory: `session:current`
It appears in the browser.
I googled that message, but I found nothing about dependency injection in Ember CLI.
Any idea?
In ember-cli you can use ember generate service <name of service> and ember generate initializer <name of initializer> to build the stubs to achieve this, which is far better than fiddling about with app.js.
You create a service basically like this:
// app/services/notifications.js
import Ember from 'ember';
export default Ember.Object.extend({
initNotifications: function() {
// setup comes here
}.on('init'),
// Implementation snipped, not relevant to the answer.
});
And the initializer, which injects the service into the component(s) of your application which need it:
// app/initializers/notifications-service.js
import Notifications from '../services/notifications';
export default {
name: 'notification-service',
after: 'auth-service',
initialize: function( container, app ) {
app.register( 'notifications:main', Notifications, { singleton: true } );
app.inject( 'component:system-notifications', 'notificationService', 'service:notifications' );
app.inject( 'service:auth', 'notificationService', 'service:notifications' );
}
};
With that, it becomes available as notificationService on the components specified.
Documentation on the subject of dependency injection in Ember can be found at http://emberjs.com/guides/understanding-ember/dependency-injection-and-service-lookup/

Best way of passing arguments to ember addon source code

TL;DR
Is it possible to pass the options from the addon's index.js file to the addon's Ember application?
More detail
Ember CLI addon's allow you to pass options to an addon by setting options in your Brocfile.js.
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var app = new EmberApp({
myAddon: {
enabled: false // TODO - Change when CLoudfront is implemented
},
});
You can then access these options in the addon's index.js file like so:
module.exports = {
name: 'my-addon',
included: function(app) {
var options = app.options.myAddon;
}
}
However, what if I want to use these options in an Ember component or view or other class in the addon? For example, a component:
import Em from 'ember';
export default Em.Component.extend({
doSomething: function() {
if (this.get('options.enabled')) {
// Then do something
}
},
});
Is it possible to pass the options from the addon's index.js file to the addon's Ember application?
Please note, I'm aware you could just pass the argument to the component in the template but that's not the point of this question. Thanks.
I think what you're trying to accomplish is best implemented using config/environment.
You can either add your options to your addons config/environment.js file. This object will be merged with you applications config/environment.js.
module.exports = function(/* environment, appConfig */) {
return {
myaddon {
enabled: true
}
};
};
Or if you are feeling funky, you can override the default behaviour of the addons config hook in index.js to manually add the options. But the happy path should be considered adding it to config/environment.js
In your component you can then import the config with:
import config from '../config/environment';
If you also need the options to be added to your app instance. You can add the options under the APP property in config/environment.js. The content of the APP property are added to the app instance. In your addon's config/environment.js put:
module.exports = function(/* environment, appConfig */) {
return {
APP: {
// Here you can pass flags/options to your application instance
// when it is created
myaddon {
enabled: true
}
}
};
};

EmberCLI app errors when using fixtures

I usually use Rails for my Ember apps. However this time we opted to decouple the API from the Ember app, and as such I'm trying EmberCLI. So far it's lovely to setup and use. However when using attempting to use fixtures it doesn't load the data.
As listed in this post I am using reopenClass when declaring the fixtures.
If I do not override the model, it does not error but the Ember inspector also shows no data was loaded. If I override my file with:
// routes/campaigns/index.js
export default Ember.Route.extend({
model: function() {
return this.store.find('campaign');
}
});
And visit the /campaigns path then I get the error I get the error Error while loading route: undefined.
From what I can find this seems to happen when Ember cannot find the data.
My router and model with obvious items like export default excluded:
// app/router.js
Router.map(function() {
this.resource('campaigns', function() {
});
});
// models/campaign.js
var Campaign = DS.Model.extend({
name: DS.attr('string')
});
Campaign.reopenClass({
FIXTURES: [
{ "id": 1, "name": "Campaign #1" },
{ "id": 2, "name": "Campaign #2" }
]
});
I have tested the same setup in a Rails app I just made, and it works perfectly. I'd love any insight people could give, as EmberCLI seems lightweight and worth the effort.
Edit: Adding my app.js file to answer question about whether I included DS.FixtureAdapter:
// Import statements
Ember.MODEL_FACTORY_INJECTIONS = true;
var App = Ember.Application.extend({
modulePrefix: 'nala', // TODO: loaded via config
Resolver: Resolver
});
loadInitializers(App, 'nala');
App.ApplicationAdapter = DS.FixtureAdapter({});
export default App;
You need to set up your application adapter located at the filepath adapters/application.js as follows:
export default DS.FixtureAdapter.extend({});
See the first paragraph under ember-cli Naming Conventions. N.B. you won't need to import DS or Ember if you're using ember-cli and have them listed in your .jshintrc file.