Ember: Local config for development - ember.js

I want to share my ember-project between all members in my team.
Since every development environment is different (OS, VM for server, etc.) I thought it would be best practice to hold an local-environmen-file in each repository clone which will be ignored by git and just holds the specific config of each team-member.
For Example in my app the application adapter holds the "host:" entry which is a computed-property which uses the local-environment-file and reads the IP of the server (where to connect to).
My current approach looks like that:
// ./config/localenv.js
module.exports = function() {
var LOCALENV = {
host: "http://192.168.1.44:3000"
};
return LOCALENV;
};
And Im importing it in my adapter like that:
// ./app/pods/application/adapter.js
import DS from 'ember-data';
import LOCALENV from 'your-application-name/config/localenv';
export default DS.RESTAdapter.extend({
host: Ember.computed(function() {
return LOCALENV.host;
})
});
Unfortunately ember returns error logs in the browser console (the referenced/imported module was not found...). What am Im doing wrong?

Related

Ember model host adapter not overiding mirage

I'm using Ember-cli-mirage to mock data. I want to slowly integrate parts of the production api which is located on my local machine at http://localhost:8000. Ember docs tell me that I should be able to set an adapter so I can have a different host for each model.
I have a customer model, and have setup ember-cli-mirage which is successfully serving data. The customer model is the first model I want to split out to localhost:8000.
I've setup adapters/customer.js with the following:
import DS from 'ember-data';
export default DS.RESTAdapter.extend( {
host: 'http://localhost:8000',
namespace: 'api/v1'
});
But when I make the call I'm getting an error:
Mirage: Error: Your Ember app tried to GET 'http://localhost:8000/api/v1/customers',
but there was no route defined to handle this request.
Define a route that matches this path in your
mirage/config.js file. Did you forget to add your namespace?
And my header inspector shows that customers is making the request to the mirage server:
Request URL:http://localhost:6543/customers
Request Method:GET
Status Code:304 Not Modified
Remote Address:[::1]:6543
I suspect it's something to do with my config/environment.js setup so I'm looking at a variation of https://github.com/samselikoff/ember-cli-mirage/issues/497#issuecomment-183458721 as a potential workaround. But I can't see why mirage won't accept the adapter overide.
Should have read back through the mirage docs for this one. There's a passthrough function that allows mirage to pass certain requests through to Ember bypassing mirage:
// mirage/config.js
import Mirage from 'ember-cli-mirage';
export default function() {
this.urlPrefix = 'http://localhost:8000';
this.namespace = '/api/v1';
// Requests for customers
this.get('/customers');
this.get('/customers/:id');
this.post('/customers');
this.del('/customers/:id');
this.patch('/customers/:id');
// Passthrough to Django API
this.passthrough('/customers');
}
To make this work in my application adapter I added:
// app/adapters/application.js
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
host: 'http://localhost:8000',
namespace: 'api/v1'
});
If this helps you in any way feel free to give this answer an upvote :)

Ember-cli-mirage not showing any data with get

I am learning Ember and I am getting stuck on making the mock api with ember-cli-mirage. I modified the config file as specified in the ember tutorial as well as on the ember-cli-mirage site, but everytime I hit the endpoint I get nothing. Here is my current config file
export default function() {
this.get('/api/users', function() {
return {
users: [
{id: 1, name: 'Zelda'},
{id: 2, name: 'Link'},
{id: 3, name: 'Epona'},
]
}
});
}
Like I said, when I go to /api/users it is just a blank page. Am I missing something here?
Thanks!
First thing first, install Ember inspector extension (for Chrome or Firefox) and look in the browser console to see if Mirage is giving you some errors. If nothing is written in there, you are not hitting the endpoint with your ember application. Basically, Mirage proxies all the request from your ember application.
So you need to generate a user model
ember g model user
and put in there the name attribute.
Create a route and in the model hook write
return this.get('store').findAll('user');
(look at the quick start tutorial if something is not clear)
So now, leveraging Ember Data, your app will request all users hitting on /users.
Now let's start with mirage, generate a mirage model
ember g mirage-model user
and follow the mirage quickstart, just adapt it to your needs :)
Start your application with ember s and you should see the request to /users.
If you want to put your api on the same domain, but with the /api prefix, then i suggest you to read about endpoint path customization
In app/mirage/config.js you can set up mock endpoints for your users:
export default function() {
this.get('/users');
this.post('/users');
this.put('/users/:id');
this.del('/users/:id');
}
You can set up your mock data by configuring fixtures in app/mirage/fixtures/users.js:
export default [
{id: 1, name: 'Zelda'},
{id: 2, name: 'Link'},
{id: 3, name: 'Epona'},
];
Mirage isn't an actual server, so you won't be able to hit the API from your browser directly. It's a mock server that lives in JavaScript memory, and is instantiated when your Ember app boots up.
To test out your mocks, have your Ember app make an API request, e.g.
// routes/application.js
export default Ember.Route.extend({
model() {
return Ember.$.getJSON('/api/users');
}
});
If everything's hooked up correctly, you should now see Mirage handling this request and logging the response data in your console.

Configure Ember's back-end to communicate with a RESTful service

There seems to be a lot of discussion on SO (e.g. these questions: A, B, C, D) and other sites (e.g the Ember docs) about configuring Ember to allow cross-origin requests. That's all fine and well, but I'd rather have Ember's back-end do the work of communicating with a remote service (Ember's server-side components to make the request, rather than the user's browser). Is this documented? Can someone provide an example?
I thought I would find it easy to modify the HTTP server backing the ember serve command. Instead, I used the --proxy flag from Ember's CLI. It allows you to use remote services to provide data.
For this to work, let's assume a remote server foo.com:3000 provides JSON data at the path /resource. Configure a controller to GET the data like so:
import Ember from 'ember';
function getRemoteResource(store){
var dfd = Ember.$.Deferred();
Ember.$.ajax('/resource')
.done(function(data){
store.createRecord('model', data);
dfd.resolve();
})
.fail(function(err){
dfd.reject(new Error("An error occurred getting data.", err));
});
return dfd.promise();
}
export default Ember.Controller.extend({
actions: {
getResource:function(){
var dataStore = this.store;
return getRemoteResource(dataStore);
}
}
});
Use a template like this to invoke the controller's action:
<h2>Remote data example</h2>
<button class="my-button" {{action 'getResource' }}>
Get resource
</button>
Assuming your code is on host bar.com, start ember like this : ember serve --proxy http://foo.com:3000. Then, open your browser to the appropriate page that loads the template (somewhere like http://bar.com:4200/index) , click the button and see that remote data is loaded.

How can I get the namespace of the including application in an Ember CLI Addon?

I'm creating an Ember CLI ember-addon, and in my addon's files I need access to the app's config. I have no way of knowing what the app including this addon will be named, so I can't simply do import ENV from 'app-name/config/environment' like I might in the application itself.
How can I access the namespace of the application that is using the ember-addon from within the addon itself, so that I can import things from that application?
You should not need to get the namespace in order to get the config.
Any setting that your addon requires should be added on to ENV.APP in config/environment.js.
For example if you wanted a MY_APP_KEY setting you would require that something like
ENV.APP.MY_APP_KEY = 'ABCDEF'; was added to config/environment.js.
You can then use an initializer to read the property off of the application instance and inject it into you addon by doing something like...
export default {
name: "my initilizer",
initialize: function(container, app) {
//get you setting off of the app instance
var key = app.get('MY_APP_KEY');
//register it
app.register('config:myAddonKey', key, { instantiate: false });
//inject it where you want to access it
app.inject('route', 'myAddonKey', 'config:myAddonKey');
}
};
You can see an example of how its done in the Ember Django Adapter
One possibility is to use an initializer:
Ember.Application.initializer({
name: 'my-component',
initialize: function(container, app) {
// you have access to 'app' here...
}
});

How to setup development environment for Ember.js + Express

I'm in the process of splitting into two different projects an Ember.js app and its Express REST API counterpart. I assumed that things would be cleaner this way.
Until then, my Express app was both serving REST endpoints and all static files like index.html and app.js. But now, ember-cli is in charge of serving the static files and the Express app handles authentication + REST.
The last issue I'm having is that I now have two different ports: ember-cli uses http://localhost:4200 and express uses http://localhost:3333. When I get the session cookie from Express upon authentication, it's never being sent on subsequent request because of same origin policy (see: How do I send an AJAX request on a different port with jQuery?).
Now if I understand correctly I have two solutions:
Setup Express to support JSONP and make sure Ember uses it too
Install a local Nginx or Apache and setup a proxy pass
The first solution is not ok because after deployment both apps will use the same domain/port. The second solution would probably work but it seems a bit ridiculous to ask developers to install a local web server to simply run an app.
I'm sure many of you have encountered that issue before. What would you suggest to make development easy?
Thanks!
Hmm. Seems like I found another solution:
Following instructions found there: http://discuss.emberjs.com/t/ember-data-and-cors/3690/2
export default DS.RESTAdapter.extend({
host: 'http://localhost:3333',
namespace: 'api',
ajax: function(url, method, hash) {
hash = hash || {}; // hash may be undefined
hash.crossDomain = true;
hash.xhrFields = { withCredentials: true };
return this._super(url, method, hash);
})
});
You will also need to add the following headers in the Express app:
// Add support for cross-origin resource sharing (localhost only)
app.all('*', function(req, res, next) {
if (app.get('env') === 'development') {
res.header('Access-Control-Allow-Origin', 'http://localhost:4200');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
}
next();
});
That's it! Last step is to make sure that Ember uses CORS only in the dev environment.
UPDATE
Ember-cli now has an integrated proxy feature that makes all the above obsolete.
From documentation: "Use --proxy flag to proxy all ajax requests to the given address. For example ember server --proxy http://127.0.0.1:8080 will proxy all your apps XHR to your server running at port 8080."