Ember howto use model field values in Controller - ember.js

I am a newbie on Ember and break my head already a couple of hours how i can use the value of a model field in a controller ?
This is my model :
import DS from 'ember-data';
export default DS.Model.extend({
id_customer: DS.attr('number'),
id_default_group: DS.attr('number'),
id_lang: DS.attr('number'),
id_gender: DS.attr('number'),
active: DS.attr('boolean'),
email: DS.attr(),
firstname: DS.attr(),
lastname: DS.attr(),
company: DS.attr(),
birthday: DS.attr('date'),
date_add: DS.attr('date'),
date_upd: DS.attr('date'),
max_payment_days: DS.attr('number'),
newsletter: DS.attr('boolean'),
note: DS.attr(),
website: DS.attr()
});
This is my route :
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel: function(){
if(!this.get('session.isAuthenticated')){
this.transitionTo('application');
}
},
model(params) {
return Ember.RSVP.hash({
customer: this.store.findRecord('customer', params.id),
address: this.store.query('address', {
orderBy: 'id_customer_fb',
equalTo: parseInt(params.id)
})
});
}
});
This is my controller :
import Ember from 'ember';
const genders = [
{ title: 'Dhr.', id_gender: '1' },
{ title: 'Mevr.', id_gender: '2' },
];
export default Ember.Controller.extend({
genders: genders,
selection: genders[1]**, <== THIS '1' MUST BE REPLACED WITH THE VALUE OF models.customer.id_gender ?????**
actions: {
chooseDestination(genders) {
this.set('selection', genders);
},
}
});
I would that the value 1 in this genders array could be the value of model.customer.id_gender ?

Yes you can.
Change selection like this :
selection: Ember.computed(function(){
let ret = this.get('genders').filterBy('id_gender', this.get('model.customer.id_gender'));
return ret.objectAt(0);
})
Please take a look at this twiddle

Related

Ember self-reference and polymorphism

there is a user model which also relates to itself as contact so user has_many contacts.
Than each contact has and belongs to many "groups". Both user and contact has one address.
I read through http://lukegalea.github.io/ember_data_polymorphic_presentation/#/ couple of times, but yet still do no understand how to setup { user | contact } <-> address relationship and a contacts <-> groups association on the Ember side.
Right now I have (a simplified representation):
// Address
export default DS.Model.extend({
city: DS.attr('string'),
profile : DS.belongsTo('profile', { polymorphic: true, async: true })
});
// Profile
export default DS.Model.extend({
name: DS.attr('string'),
phone: DS.attr('string'),
address: DS.belongsTo('address', {async: true})
});
// Contact
export default Profile.extend({
groups: DS.hasMany('group')
});
// User
export default Profile.extend({
});
Here is the JSON
// GET /contacts
{
"contacts":[
{
"name":"Conrad",
"address_id":"1",
"id":1
},
{
"name":"Greyson",
"address_id":"2",
"id":2
},
{
"name":"Tommie",
"address_id":"3",
"id":3
}
]
}
// GET /addresses
{
"addresses":[
{
"city":"West Lillaton",
"profile_id":"0",
"profile_type":"Contact",
"id":1
},
{
"city":"Weissnatborough",
"profile_id":"1",
"profile_type":"Contact",
"id":2
},
{
"city":"Predovicton",
"profile_id":"2",
"profile_type":"Contact",
"id":3
},
{
"city":"VKHA",
"profile_id":1,
"profile_type":"User",
"id":4
}
]
}
// GET /users
{
"users":[
{
"name":"Emile",
"address_id":4,
"id":1
}
]
}
As far as I understand there is no need in polymorphic here, because you wrote: "user model which also relates to itself". You should set reflexive relation contacts for user model.
When you want to define a reflexive relation, you must either explicitly define the other side, and set the explicit inverse accordingly, and if you don't need the other side, set the inverse to null.
http://guides.emberjs.com/v1.12.0/models/defining-models/#toc_reflexive-relation
// User
export default DS.Model.extend({
name: DS.attr('string'),
phone: DS.attr('string'),
address: DS.belongsTo('address', {async: true, inverse: 'user'})
groups: DS.hasMany('group', {async: true}),
contacts: DS.hasMany('user', { inverse: null }),
});
// Address
export default DS.Model.extend({
city: DS.attr('string'),
user: DS.belongsTo('user', { async: true, inverse: 'address' })
});
// Group
export default DS.Model.extend({
name: DS.attr('string'),
users: DS.hasMany('user', {async: true}),
});
If you'd like user and contact to be different ember models then
address belongsTo polymorphic profile:
// Profile
export default DS.Model.extend({
name: DS.attr('string'),
phone: DS.attr('string'),
address: DS.belongsTo('address', {async: true, inverse: 'profile'})
});
// Contact
export default Profile.extend({
groups: DS.hasMany('group', {async: true}),
user: DS.belongsTo('user', { async: true, inverse: 'contacts' })
});
// User
export default Profile.extend({
contacts: DS.hasMany('contact', { inverse: 'user' }),
});
// Address
export default DS.Model.extend({
city: DS.attr('string'),
profile: DS.belongsTo('profile', { polymorphic: true, async: true, inverse: 'address' })
});
// Group
export default DS.Model.extend({
name: DS.attr('string'),
contacts: DS.hasMany('contact', {async: true}),
});
Note: proper paylod for GET addresses should be :
// GET /addresses
{"addresses":[
{
"id":1,
"city":"West Lillaton",
"profile": {"id:"1", "type":"Contact"},
},{
"id":2,
"city":"West Lillaton",
"profile": {"id:"2", "type":"User"},
}
]}

Ember model find records without server request

I have an ember model Category:
export default DS.Model.extend({
name: DS.attr('string'),
img: DS.attr('string'),
url: DS.attr('string'),
cnt: DS.attr('number'),
// parent_id: DS.belongsTo('category', {
// inverse: 'children',
// async: true
// }),
parent_id: DS.attr('string'),
// children: DS.hasMany('category', {
// inverse: 'parent_id',
// async: true
// }),
children: DS.attr(),
isSelected: false,
isExpanded: false,
hasChildren: function() {
return this.get('children').get('length') > 0;
}.property('children').cacheable(),
isLeaf: function() {
return this.get('children').get('length') == 0;
}.property('children').cacheable()
});
In my index route I have:
export default Ember.Route.extend({
model: function() {
var store = this.store;
return Ember.ArrayProxy.create({
categories: store.find('category'),
menuTopCategories: store.find('category', { parent_id: 1 })
});
}
});
I'm using a RESTAdapter so the store.find will send two requests to the server: categories and categories?parent_id=1.
I would like to have only the first request and then filter through the categories. I tried store.all - since I saw it reuses the already fetch data, but I can't manage to apply the filter.
I've rewritten the menuTopCategories and I don't see a new request:
menuTopCategories: store.filter('category', function(category) {
return category.get('parent_id') === "1";
})
My problem right now is to get the root category (first one) without hardcoding the parent_id.

Ember.js error when saving one-to-many relationship model

I have problem creating record on one-to-many relationship. I use Ember 1.7 with Ember Data 1.0.0-beta.10.
app/models/transaction.js
import DS from 'ember-data';
var Transaction = DS.Model.extend({
code: DS.attr('string'),
created_at: DS.attr('date', {
defaultValue: function() { return new Date(); }
}),
customer: DS.belongsTo('customer', { embedded: 'always', async: true }),
details: DS.hasMany('transactiondetail', { embedded: 'always', async: true }),
is_cash_payment: DS.attr('boolean')
});
export default Transaction;
app/models/transactiondetail.js
import DS from 'ember-data';
var TransactionDetail = DS.Model.extend({
item: DS.belongsTo('item', { embedded: 'always', async: true }),
max_returned_at: DS.attr('date'),
returned_at: DS.attr('date'),
price: DS.attr('number')
});
export default TransactionDetail;
app/serializers/transaction.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
customer: { serialize: 'records', deserialize: 'id' },
details: { serialize: 'records', deserialize: 'ids' }
}
});
app/serializers/transactiondetail.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
item: { serialize: 'records', deserialize: 'id' },
}
});
app/controllers/transaction/create.js
import Ember from 'ember';
export default Ember.ObjectController.extend(, {
needs: ['transactions'],
transactionCode: '',
dateNow: new Date(),
maxReturnedAt: maxReturnedAt,
selectedItem: [],
selectedCustomer: null,
totalPrice: totalPrice,
payValue: 0,
change: 0,
isCashPayment: true,
actions: {
create: function() {
var self = this;
var record = this.store.createRecord('transaction', {
code: this.get('transactionCode'),
customer: this.get('selectedCustomer'),
is_cash_payment: this.get('isCashPayment')
});
this.get('selectedItem').forEach(function( item ) {
var transactionDetail = self.store.createRecord('transactiondetail', {
item: item,
max_returned_at: self.get('maxReturnedAt'),
price: item.get('price')
});
record.get('details').then(function(selectedRecord) {
selectedRecord.pushObject( transactionDetail );
});
});
record.save().then( function() {
self.get('controllers.transactions.model').pushObject({});
self.clearForm();
self.transitionToRoute('transactions');
});
},
goBack: function() {
this.transitionToRoute('transactions');
},
}
});
If I do create record, I got an error like this.
Error: Assertion Failed: The content property of DS.PromiseArray should be set before modifying it
at new Error (native)
at Error.EmberError (http://machine.dev:4200/assets/vendor.js:26712:23)
at Object.Ember.assert (http://machine.dev:4200/assets/vendor.js:16896:15)
at EmberObject.extend._replace (http://machine.dev:4200/assets/vendor.js:45514:15)
at EmberObject.extend._insertAt (http://machine.dev:4200/assets/vendor.js:45529:14)
at EmberObject.extend.pushObject (http://machine.dev:4200/assets/vendor.js:45573:14)
at apply (http://machine.dev:4200/assets/vendor.js:31554:27)
at superWrapper [as pushObject] (http://machine.dev:4200/assets/vendor.js:31132:15)
at eval (pw-store/controllers/transactions/create.js:74:35)
at Array.forEach (native) vendor.js:27637logToConsole vendor.js:27637RSVP.onerrorDefault vendor.js:41089__exports__.default.trigger vendor.js:59652Promise._onerror vendor.js:60651publishRejection vendor.js:58914(anonymous function) vendor.js:42243DeferredActionQueues.invoke vendor.js:13808DeferredActionQueues.flush vendor.js:13858Backburner.end vendor.js:13321Backburner.run vendor.js:13376apply vendor.js:31557run vendor.js:30173__exports__.default.EmberObject.extend._bubbleEvent vendor.js:50350(anonymous function) vendor.js:50298jQuery.event.dispatch vendor.js:4759jQuery.event.add.elemData.handle vendor.js:4427
Uncaught Error: Assertion Failed: Error: Assertion Failed: The content property of DS.PromiseArray should be set before modifying it
UPDATE
I have update my Ember Data to 1.0.0-beta.11 as suggested by Kingpin2k, but I got undefined error (see my comment below). I guess I do mistake on model and/or serializer but I have no idea how to fix it. Any help?

createRecord with ember-data + ember-data-django-rest-adapter

I'm currently working on creating an ember application using ember/ember-data/ember-data-django-rest-adapter with Django backend.
I'm having issue creating record when there's belongsTo and hasMany relationship going on.
I currently have this code:
App.Article = DS.Model.extend({
title: attr(),
description: attr(),
authors: hasMany('author'),
category: belongsTo('page'),
slug: attr(),
content: attr(),
articleContent: Ember.computed.alias("content"),
published: attr(),
publish_from: attr(),
isScheduled: function() {
return moment().isBefore(moment(this.get('publish_from')));
}.property('publish_from'),
articlePublishDate: function() {
return moment(this.get('publish_from')).format('MMMM Do YYYY');
}.property('publish_from'),
articlePublishTime: function() {
return moment(this.get('publish_from')).format('h:mm a');
}.property('publish_from'),
//content_type: belongsTo('content_type', { async: true }),
content_type: attr()
});
App.Page = DS.Model.extend({
title: attr(),
description: attr(),
pageContent: attr(null, {
key: 'content'
}),
templateFile: attr(null, {
key: 'template'
}),
slug: attr(),
tree_path: attr(),
tree_parent: belongsTo('page'),
site: attr()
});
App.Author = DS.Model.extend({
name: attr(),
slug: attr(),
description: attr(),
text: attr(),
email: attr(),
photo: attr(),
user: belongsTo('user'),
});
// create article
App.ArticleCreateController = Ember.ObjectController.extend({
editMode: false,
allAuthors: function() {
return this.store.find('author');
}.property(),
allPages: function() {
return this.store.find('page');
}.property(),
actions: {
save: function(session) {
var self = this;
var article = this.get('model');
var newArticle = this.store.createRecord('article', {
content_type: "19",
content: article.get('articleContent'),
description: article.get('description'),
publish_from: article.get('publish_from'),
published: article.get('published'),
slug: article.get('slug'),
title: article.get('title')
});
this.store.find('page', 3).then(function(page) {
newArticle.set('category', page);
});
newArticle.save();
}
}
});
All I really want to do is POST data like this to apiRoot/articles/ (along with other attributes, but those are working the way they should)
authors: [1,3,5], // hasMany
category: 3 // belongsTo
But when I make a POST request, category returns as null for some reason. All I want to extract from it is just the id itself. Also, I have no clue how to extract the array of authors. I tried posting the data, and it tells me something about it needing to be 'App.Author'.
First, at the current time you need a fork of ember-data because async create is currently broken (as it's a promise and the internal serializer won't wait for it to resolve).
Pull down this branch, do a npm install + grunt test to build the adapter. Also you need to use the forked build of ember-data in that branch'es test lib directory (until ember-data pulls in the fix for this)
https://github.com/toranb/ember-data-django-rest-adapter/tree/asyncBelongsToHasManyWIP
Then inside your controller you can do something like this to "create" the customer and appointment (notice -async belongsTo/hasMany relationship)
App.Customer = DS.Model.extend({
name: DS.attr('string'),
appointments: DS.hasMany('appointment', { async: true})
});
App.Appointment = DS.Model.extend({
details: DS.attr('string'),
customer: DS.belongsTo('customer', { async: true})
});
var customer = {
name: 'foobar'
}
this.store.createRecord('customer', customer).save().then(function(persisted) {
var appointment = {
details: 'test',
customer: persisted
}
return self.store.createRecord('appointment', appointment).save().then(function(apt) {
persisted.get('data').appointments.pushObject(apt);
router.transitionTo('index');
});
});

Find record from belongsTo association in Ember.js

How can I get the associated record from an Ember model? Or: how to get the record from the Promise Object?
Customer model
Docket.Customer = DS.Model.extend({
name: DS.attr('string'),
initial: DS.attr('string'),
description: DS.attr('string'),
number: DS.attr('string'),
archived: DS.attr('boolean'),
projects: DS.hasMany('project',{ async: true })
});
Project model
Docket.Project = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
number: DS.attr('string'),
archived: DS.attr('boolean'),
customer: DS.belongsTo('customer', { async: true })
});
Find method
var project = this.store.find('project', id).then(function(data) {
console.log(data.get('customer').toString());
});
Console output
<DS.PromiseObject:ember654>
JSON response
{"projects":[
{
"id":1,
"name":"test",
"number":"a310",
"description":null,
"archived":false,
"customer_id":22
}
]};
use another then on the get :)
var project = this.store.find('project', id).then(function(data) {
data.get('customer').then(function(c){
console.log(c);
}
});