Return the first element from an array as a computed property from an Ember controller subclass
I am trying to return the first element of my array as a computed property in my template from my controller. My code is below. I am 100% about my array and template. The problem is my syntax in the controller. Basically my array is works created from Work objects. And ideally I would return the first Work item. Is this possible in javascript?
Best.
// controller works.js
import Ember from "ember";
export default Ember.Controller.extend({
firstElement: function () {
var arr = this.get('model');
return arr[0];
console.log(arr[0]);
}.property('Work')
});
// works.js template
<div class="right">
{{#liquid-with model as |currentModel|}}
{{firstElement}}
{{/liquid-with}}
</div>
// route works.js
import Ember from 'ember';
var Work = Ember.Object.extend({
name: '',
year: '',
description:'',
image:'',
logo:'',
work_id: function() {
return this.get('name').dasherize();
}.property('name'),
});
var minibook = Work.create({
id: 1,
name: 'MINIBOOK',
year: '2014',
description:'MiniBook is an iphone app that explores storytelling in its own format. The format',
image:'assets/images/minibook_iphone.png',
logo:'assets/images/minibook_logo.png'
});
var poetics = Work.create({
id: 2,
name: 'POETICS',
year: '2013',
description:'Lorem Ipsum Poetics',
image:'assets/images/poetics_iphone.png',
logo:'assets/images/poetics_logo.png'
});
var WorksCollection = Ember.ArrayProxy.extend(Ember.SortableMixin, {
sortProperties: ['id'],
sortAscending: true,
content: []
});
var works = WorksCollection.create();
works.pushObjects([poetics, minibook]);
export default Ember.Route.extend({
model: function() {
return works;
}
});
source to share
This will work.
Long way to go (just to improve your computed property code):
// controller work.js
import Ember from "ember";
export default Ember.Controller.extend({
firstElement: function () {
return this.get('model').get('firstObject'); // or this.get('model.firstObject');
}.property('model.[]')
});
1) you set works
as model
in route so you can get it as model
in controller
2) .property(model.[])
Means a computed property of an array, so adding and removing an array element will trigger an update. You can also select a specific property like.property(model.@each.modelProperty)
3) fistObject
is the correct method (not [0]
) since you are working with Ember.ArrayProxy see http://emberjs.com/api/classes/Ember.ArrayProxy.html
4) you can use {{firstElement}} in your template
Lazy way :
1) set model in route as array or as promise resolved in array
// works = ... as is
export default Ember.Route.extend({
model: function() {
return works;
}
});
2) get model.firstObject
directly in the template
//template works
{{model.firstObject}} {{!-- first object of model array --}}
{{model.firstObject.name}} {{!-- name of first object --}}
UPDATE: Use correct iteration syntax http://ef4.github.io/liquid-fire/#/helpers/liquid-with/10
{{#liquid-with model as currentModel}}
{{currentModel.firstObject.name}}
{{/liquid-with}}
source to share
A slightly more updated (or different) example
import Controller from '@ember/controller';
import { readOnly } from '@ember/object/computed';
export default Controller.extend({
firstElement: readOnly('model.firstObject')
});
Or if you want bi-directional data flow (you can install firstElement
)
import Controller from '@ember/controller';
import { alias } from '@ember/object/computed';
export default Controller.extend({
firstElement: alias('model.firstObject')
});
source to share