How to translate controller member arrays in Ember-i18n? - ember.js

In my customer controller I have defined some constant arrays that are used for populating select input (dropdown) options.
import Ember from 'ember';
export default Ember.Controller.extend({
occupations: [
{code: 'student', name: "Student"},
{code: 'worker', name: "Worker"},
{code: 'retired', name: "Retired"},
{code: 'other', name: "Other"}
]
});
Normal solution would be using translationMacro function t() or this.get('i18n').t() around translation key, but they can't be used in such situation as "this" inside object or array will not refer to controller.
What is best practice for solving such situation?

You can make occupations a property:
import Ember from 'ember';
export default Ember.Controller.extend({
i18n: Ember.inject.service(),
occupations: function() {
var i18n = this.get('i18n');
return [
{code: 'student', name: i18n.t('occupations.student') },
{code: 'worker', name: "Worker"},
{code: 'retired', name: "Retired"},
{code: 'other', name: "Other"}
];
}.property()
});

Related

How can I add default values for ember has many relationship?

I'm using Ember 2.5.0 and I have two models service and availability which looks like:
// availability
import DS from 'ember-data';
export default DS.Model.extend({
day: DS.attr('string'),
enabled: DS.attr('boolean'),
startAt: DS.attr('string'),
endAt: DS.attr('string'),
service: DS.belongsTo('service')
});
And service which looks like:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
availabilities: DS.hasMany('availability',
{
defaultValue:
[
{
day: 'saturday',
enabled: false,
startAt: '',
endAt: ''
},
{
day: 'sunday',
enabled: false,
startAt: '',
endAt: ''
}
]
}
)
});
As you can see I was trying to use defaultValue but with no luck. For new route I want to set default values if we are creating a new service record.
Any help is appreciated.
The argument hash that DS.hasMany only accepts two properties: async and inverse. It doesn't accept a defaultValue property though. (source).
But fear not, Eki Eqbal! I think you can accomplish something similar by using your model's ready() hook.
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
availabilities: DS.hasMany('availability', { async: true }), // is the data loaded async?
ready() { // fires when the model is loaded from server or created locally
if (!!this.get('availabilities')) {
// don't set to defaults if availabilities is not null
return;
}
var saturday = this.store.createRecord('availability', {
day : 'saturday',
enabled : false,
startAt : '',
endAt : ''
});
var sunday = this.store.createRecord('availability', {
day : 'sunday',
enabled : false,
startAt : '',
endAt : ''
});
this.get('availabilities').pushObjects([saturday, sunday]);
}
});

How to extract a "ComputedProperty" to it's real value?

I'm trying to implement amCharts into a project, and it looks like when I pass it the EmberData model as it's dataProvider, it can't understand the promises.
I've tried to fix this by creating a computed property in my controller that looks like:
Route:
--route.js
import Ember from 'ember';
const {Route, RSVP} = Ember;
export default Route.extend({
queryParams: {
start: {refreshModel: true},
stop: {refreshModel: true}
},
model(params) {
let filter = {
filter: {
start: params.start,
stop: params.stop
}
};
return RSVP.hash({
users: this.store.query('userActivity', filter, {async: false}),
});
},
setupController(controller, model) {
controller.set('model', model);
controller.set('users', model.users);
},
});
Controller (there are other parts I've stripped out, but they aren't relevant, suffice to say they just change the query params which triggers a model refresh from route):
--controller.js
import Ember from 'ember';
const {Controller, computed, get, set} = Ember;
export default Controller.extend({
queryParams: [ 'start', 'stop' ],
dataProvider: computed('users', function () {
let users = get(this, 'users')
.map(function (user) {
return {
calls_out: user.calls_out,
calls_in: user.calls_in,
}
});
console.log(users);
return users;
}),
});
However, when I log this I get the following:
0: Object +
calls_in: ComputedProperty
calls_out: ComputedProperty
__proto__: Object
1: Object
2: Object
which means the object that amCharts needs to work with is still not the raw data. Is there a way to extract the data out into numbers rather than a Promise or a ComputedProperty?
Thanks!
Edit - adding userActivity model as requested:
import DS from 'ember-data';
import Ember from 'ember';
export default DS.Model.extend({
// Attributes
title: DS.attr('string'),
first_name: DS.attr('string'),
last_name: DS.attr('string'),
calls_in: DS.attr('number'),
calls_out: DS.attr('number'),
// Computed Attributes
full_name: Ember.computed('first_name', 'last_name', function () {
return `${this.get('first_name')} ${this.get('last_name')}`;
}),
// Relationships
user: DS.belongsTo('user')
});
Every attribute on a DS.Model is defined with DS.attr() and will be a Computed Property. This is required so that ember-data ca track changes and rollback or update attributes.
For your use case best is to use getProperties:
const {computed,get,getProperties} = Ember;
...
dataProvider: computed('users.#each.calls_out', 'users.#each.calls_in', function () {
return get(this, 'users').map(u => getProperties(u, 'calls_out', 'calls_in'));
})
Then get(this, 'dataProvider') will give you a raw Javascript Array with raw Javascript Objects with raw strings (or numbers, depending on your DS.attr).
What is in the "user" class? Are they Ember object? You may provide more code.
If "calls_in" and "calls_out" are computed properties of this user class, you should call them like this:
let users = get(this, 'users')
.map(function (user) {
return {
calls_out: user.get('calls_out'),
calls_in: user.get('calls_in'),
}
});

Model in Payload not recognized

I have some models with similar names:
issue-statuse.js
issue-type.js
issue-type is working perfectly, but issue-statuse is causing trouble:
WARNING: Encountered "issue_statuses" in payload, but no model was found for model name "issue-status" (resolved model name using soporte#serializer:issue-statuse:.modelNameFromPayloadKey("issue_statuses"))
//<!--app/adapters/application.js-->
import Ember from 'ember';
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
namespace: 'api/v1',
host: 'http://127.0.0.1:3000',
coalesceFindRequests: true,
headers: {
withCredentials: true,
Authorization: 'Basic eG9qbzpzZWNyZXQ=',
crossDomain: true
},
pathForType: function(type) {
return Ember.String.underscore(type)+'s';
}
});
// added a 's' for pluralize names, as when we need in underscore are in singular once again ...
//<!--app/models/issue-statuse.js-->
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
short: DS.attr('string'),
plural: DS.attr('string'),
created_at: DS.attr('date'),
active: DS.attr('boolean')
});
I have a workaround in a Serializer, I don't like it but with it it's working fine:
//<<!--app/serializers/issue-statuse.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
modelNameFromPayloadKey: function(payloadKey) {
if (payloadKey === 'issue_statuses') {
return this._super("issue-statuse"); //this._super(payloadKey.replace('blog/', ''));
} else {
return this._super('issue-statuse'); //this._super(payloadKey);
}
}
});
But if I use this Serializer, I've got a Deprecation Warning:
Your custom serializer uses the old version of the Serializer API, with `extract` hooks. Please upgrade your serializers to the new Serializer API using `normalizeResponse` hooks instead.
So, I have two options, first one is try to solve why Ember is not finding my model, and the second, use the serializer and try to understand the deprecation and how to eliminate it.
I would prefer option one :-)
Thanks,
edit
It was a typo here in the name of the model file, it's singular:
//<!--app/models/issue-statuse.js-->
edit 2
I've removed completely the app/serializers/issue-statuse.js and created an initializer with the inflector:
//<!--/app/initializers/inflector.js-->
import Ember from 'ember';
export function initialize(/* container, application */) {
var inflector = Ember.Inflector.inflector;
inflector.uncountable('aamc-pcrs');
inflector.irregular('issue-statuse', 'issue-statuses');
}
export default {
name: 'inflector',
initialize: initialize
};
edit 3
I'm using the
pathForType: function(type) {
return Ember.String.underscore(type)+'s';
},
in the Adaptor for changing - for _
My Backend API wants issue_statuses instead of issue-statuses for example. Maybe I can just rename the table in the inflector and remove also this line ...

Error while processing route error in ember.js with ember-data

I'm trying to create an app using ember.js and ember-data, using the following versions:
DEBUG: Ember : 1.7.0
DEBUG: Ember Data : 1.0.0-beta.9
DEBUG: Handlebars : 1.2.1
DEBUG: jQuery : 2.1.0
I'm using the RESTAdapter to connect to an api I wrote using node.js.
As soon as I load the app I keep getting the following error:
Error while processing route: students undefined is not a function TypeError: undefined is not a function
at http://localhost:9000/scripts/vendor/ember-data.js:12006:34
at tryCatch (http://localhost:9000/scripts/vendor/ember.js:45818:16)
at invokeCallback (http://localhost:9000/scripts/vendor/ember.js:45830:17)
at publish (http://localhost:9000/scripts/vendor/ember.js:45801:11)
at http://localhost:9000/scripts/vendor/ember.js:29069:9
at DeferredActionQueues.invoke (http://localhost:9000/scripts/vendor/ember.js:634:18)
at Object.DeferredActionQueues.flush (http://localhost:9000/scripts/vendor/ember.js:684:15)
at Object.Backburner.end (http://localhost:9000/scripts/vendor/ember.js:147:27)
at Object.Backburner.run (http://localhost:9000/scripts/vendor/ember.js:202:20)
at apply (http://localhost:9000/scripts/vendor/ember.js:18382:27)
Here's the code I'm using (loaded in the same order I pasted it):
app.js
var App = window.App = Ember.Application.create({
LOG_ACTIVE_GENERATION: true,
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: false,
LOG_VIEW_LOOKUPS: true
});
store.js
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000',
serializer: DS.RESTSerializer.extend({
primaryKey: function(type) {
return '_id';
},
serializeId: function(id) {
return id.toString();
}
})
});
models/student.js
App.Student = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
nationality: DS.attr('string'),
createdAt: DS.attr('date')
});
routes/app_route.js
App.StudentsRoute = Ember.Route.extend({
model: function() {
return this.store.find('student');
}
});
router.js
App.Router.map(function () {
this.resource('students', {path: '/'});
});
And the following is the response of the API:
{
students: [
{
nationality: "Lorem",
lastName: "Doe",
firstName: "John",
_id: "53f87200f3750319b4791235",
createdAt: "2014-08-23T10:50:40.661Z"
},
{
nationality: "Lorem",
lastName: "Doe",
firstName: "John",
_id: "53f87299f3750319b4791234",
createdAt: "2014-08-23T10:50:40.661Z"
}
]
}
It looks like the store is not loading the data from the API, but the JSON data format looks fine. Any idea of what could be wrong?
Thanks!
So after searching more on Stack Overflow, I've figured out that the serializer has now to be in a separate class than the RESTAdapter, so the working code is the following:
store.js
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000'
});
App.ApplicationSerializer = DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
Here's an updated answer for people using ember-cli.
ember g adapter application #=> creates app/adapters/application.js
ember g serializer application #=> creates app/serializers/application.js
In app/adapters/application.js:
import DS from 'ember-data';
export default DS.RestAdapter.extend({
host: 'http://localhost:3000'
});
In app/serializers/application.js:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
I was getting this error, and it had nothing to do with any of the usual suspects.
In coffeescript, I had started defining a model.
App.Cost = DS.Model.extend
amount: DS.attr 'number'
active: DS.attr 'boolean'
To create a second model, I c/p my first model in and deleted the attributes:
App.Cost = DS.Model.extend
The went back and tried to run a seemingly unrelated model
localhost:3000/products
Which resulted in the error
Error while processing route: products.index
Simply making sure my model was named correctly solved the error:
App.Cost = DS.Model.extend(...)
App.Price = DS.Model.extend(...) <- instead of repeating the Cost model
This was re-produceable, so I thought it might be helpful to others.

using fixtures with ember-cli model blueprints

Ok, this may be just a basic JS question. I'm trying to create a model in ember-cli. I've used the blueprints to make the initial file. That gives me
import DS from 'ember-data';
export default DS.Model.extend({
});
How would I add a fixture to this?
This is some code I'm using with fixtures. The main thing is Recipe.reopenClass, Recipe.Fixtures isn't correct.
import DS from 'ember-data';
var Recipe = DS.Model.extend({
title: DS.attr('string'),
steps: DS.attr(),
description: DS.attr('string')
});
Recipe.reopenClass({
FIXTURES: [
{
id: 1,
title: "Spaghetti and meat",
steps: ["Cook noodles", "add meat", "eat the food"],
description: "ITS NOODLES AND MEAT"
},
{
id: 2,
title: "Gyro",
steps: ["get lamb", "eat greek taco"],
description: "ITS A TACO"
}
]
});
export default Recipe;
Then in adapters/application.js
import DS from 'ember-data';
export default DS.FixtureAdapter.extend();
Add this to your Brocfile
app.import({
development: 'vendor/ember-data/ember-data.js',
production: 'vendor/ember-data/ember-data.prod.js'
}, {
'ember-data': [
'default'
]
});