Ember Cli Inflector adjustments - ember.js

Where/how can i adjust the Ember.Inflector Class / create an instance of it that ember-cli picks up?
Thanks!

I generated an initializer and put this data there. This ensures it loads before anything that might need it. Like the model, adapter, or serializer.
initializers/inflector.js
import Ember from 'ember';
export function initialize(/* container, application */) {
var inflector = Ember.Inflector.inflector;
inflector.uncountable('aamc-pcrs');
}
export default {
name: 'inflector',
initialize: initialize
};

I placed it in the model file and it worked fine:
import DS from 'ember-data';
import Ember from 'ember';
var inflector = Ember.Inflector.inflector;
inflector.irregular('nota', 'notas');
inflector.singular(/nota/, 'nota');
export default DS.Model.extend({
title: DS.attr('string'),
description: DS.attr('string'),
language: DS.attr('string'),
body: DS.attr('string')
});

The Ember Guides covers this in Models - Customizing Adapters:
Create the file app/models/custom-inflector-rules.js:
import Inflector from 'ember-inflector';
const inflector = Inflector.inflector;
inflector.irregular('formula', 'formulae');
inflector.uncountable('advice');
// Meet Ember Inspector's expectation of an export
export default {};
Then in app/app.js add the line:
import './models/custom-inflector-rules';
And if you want to use this in a unit test for a serializer/adapter then you can just import the custom-inflector-rules file into the test.

Related

Add column to existing ember model

Wow this is hard to find.
I have an existing model in ember and I would like to add a new column. I have't been able to see how to generate this from the CLI, so have manually added it to my component.js and models/post.js. I've added the field to my form and the handlebar to my view. Checking Firebase I can confirm I'm not updating the field.
In Rails I would simply run rails generate migration add_snippet_to_posts snippet:string but doing this in Ember just creates a new model.
model/post.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
author: DS.attr('string'),
createdDate: DS.attr('date'),
text: DS.attr('string'),
snippet: DS.attr('string') #<=manually added this.
});
component.js
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
createPost: function (model) {
this.sendAction('createPost', model);
// Clear each input field
this.set('newPost.title', null);
this.set('newPost.author', null);
this.set('newPost.text', null);
this.set('newPost.snippet', null); #<= manually added this
}
}
});
How do I do this?
Solved
Needed to update routes/index.js too:
import Ember from 'ember';
export default Ember.Route.extend({
model: function () {
return this.store.findAll('post');
},
actions: {
createPost: function (model) {
let post = this.store.createRecord('post', {
title: model.title,
text: model.text,
author: model.author,
snippet: model.snippet, # <= add this too
createdDate: new Date()
});
post.save();
}
}
});
The official answer would be that you cannot just add an attribute with ember-CLI to a model that has already been created - and at the same time, update everything it may effect throughout your app. You have to manually write the attributes and how they are used in routes/components/templates etc.
That sounds awesome that Rails can just know all that stuff. : )

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 ...

Computer Property not updating on hasMany

I have a pretty simple model:
//models/build
import DS from 'ember-data';
export default DS.Model.extend({
shipments: DS.hasMany('shipment')
});
I need to update a computer property whenever a new shipment is added or removed, so I'm using my controller, like this:
//controllers/build
import Ember from 'ember';
export default Ember.Controller.extend({
init: function() {
this.get('allShips');
this.get('ships');
},
allShips: Ember.computed.alias('model.shipments'),
ships: function() {
console.log('updating ships');
}.property('model.#each.shipments')
});
I'm not consuming the computer properties in my template anywhere, I just need to keep them updated to do some computational work so I'm just getting them in the init function. I'm getting "updating ships" in the console when I'm entering the build route correctly, but after that it won't update no matter how many shipments I add or remove.
I've tried many different properties, model.ships.#each, allShips, #each.allShips, allShips.#each, and dozens of all combinations, but all were in vain. I've never had this kind of trouble with computer properties so any advice would be appreciated.
The placement of #each is incorrect - it should be after model.shipments.
As one of the comments state - if you're not accessing properties (e.g. model.shipments.#each.id then you should observe models.shipments.[].
For some reason the computed property only updates for me when returning an array - not returning a value or returning any type of value other than an array fails.
Model
//models/build
import DS from 'ember-data';
export default DS.Model.extend({
shipments: DS.hasMany('shipment')
});
Controller
//controllers/build
import Ember from 'ember';
export default Ember.Controller.extend({
init: function() {
this.get('allShips');
this.get('ships');
},
allShips: Ember.computed.alias('model.shipments'),
ships: function() {
var ships = this.get('model.shipments');
console.log('updating ships');
return [];
}.property('model.shipments.#each')
});
It's probably best to observe model.shipments.[] if you're not returning a value:
//controllers/build
import Ember from 'ember';
export default Ember.Controller.extend({
doShipsWork: function() {
console.log('updating ships');
}.observes('model.shipments.[]')
});

Can't connect to Ember store (Ember CLI)

Ember app, using Ember CLI, ember-data and http-mock.
I can't seem to connect to the store from the clubs/index route.
This seems to be the offending code. If I remove the call to the store, and include an inline model everything works fine. Nop idea why it can't find the store.
// clubs/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('club');
}
});
The http-mock works just fine when I curl it:
curl -H "ContentType:application/json" http://localhost:4200/api/clubs
Everything else is pretty standard:
// router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.resource('clubs', function() {
});
});
export default Router;
// club.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string')
});
Any help much appreciated!
The problem looks to be that your app is hitting /clubs while your api is located at /api/clubs. To fix this you can create an ApplicationAdapter in app/adapters/application.js to properly namespace your api:
import DS from 'ember-data';
export default DS.ActiveModelAdapter.extend({
namespace: 'api'
});

Ember CLI - Error when using moment.js in route

I have imported moment.js into my project and it seems to work just fine in my controllers but for some reason it is not working in my routes.
Controller:
// controllers/users.js
import Ember from 'ember';
export default Ember.Controller.extend({
date: function() {
alert(moment().format('X'));
}.property()
...
});
Route:
// routes/users.js
// (Error: /routes/users.js: line 5, col 29, 'moment' is not defined.
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var data = { start: moment().startOf('month').startOf('day').format('X') };
return this.store.find('event', data);
}
});
Brocfile:
var app = new EmberApp();
app.import('vendor/moment/moment.js');
I guess this is a JsHint Error. You may want to add the following comment to your Route code.
/* global moment:true */
import Ember from "ember";
....
Also (from ember-cli documentation):
If you want to use external libraries that write to a global namespace (e.g. moment.js), you need to add those to the predef section of your project’s .jshintrc file and set its value to true. If you use the lib in tests, need to add it to your tests/.jshintrc file, too.
Then you don't have to do it to every file your using moment.js in.