Getting an object and its attribute in Ember data - ember.js

I'm struggling to do some of the simplest tasks in Ember data - getting hold of a model object and reading its attributes.
I just figured out to get a model's attribute, you can do App.Model.find(id).get('attr_name').
App.Model.find(id) does not return an object, but a class (a Promise) instead.
What is the proper way of obtaining the object? Or perhaps do you not get the object ever, but just getting or setting the attributes of the object instead?

What is the proper way of obtaining the object?
Pass a success function to the model promise returned by find(id):
App.Model.find(1).then(function(record) {
console.log('Found record: ', record.toString());
console.log('Inspecting record...', Em.inspect(record));
console.log('Serializing record...', record.serialize());
});

Here is an update after the Ember Data updates in Sept 2013:
To get the attribute of an object identified by its ID in the router or the controller, do:
this.store.find('model', 'insert_id_of_obj').then(function(obj){
console.log(obj.get('insert_attribute_name'))
});
If you want to test it in the console, do:
App.__container__.lookup('store:main').find('model', 'insert_id_of_obj').then(function(obj){
console.log(obj.get('insert_attribute_name'))
});

Related

Iterating over DS.hasMany in Ember data

I have a real struggle with Ember.
In my model I have an attribute:
options: DS.hasMany('UserOptions', {async: false})
In a view linked to this model I can easily access this property by e.g.:
{{#each options AS |option|}}
something....
{{/each}}
and that works like a charm.
However when I try to access this model value in controller with:
this.get('model.options')
instead of getting a lovely array of payment options, I get an ember model array of objects, and there's no way I can access the actual data.
Do you guys have any idea how do I access this data in controller and process it?
Thanks!
this.get('model.options') will give you RSVP.Promise, so you need to work with asynchronous code. Use:
this.get('model.options').then(options => {
options.forEach(option => {
// do what you need with option
})
});
Below code solved my case:
#get('model.options').toArray().forEach((item) ->
console.log(item.get('parameter_name')]
)
That's true that console.log(#get('model')) was throwing something strange in console, however when I asked for a specific parameter, it was there!
My problem was that I was trying to print out an entire object instead of a specific value. The values were there, it just didn't print the entire object for a reason.

How do I save all locally created records in ember / ember data?

Currently, the Ember Data filter method has been deprecated. What's the best way to approach saving all new/updated records of a particular type?
You can call save() on a RecordArray so I have been doing:
this.get('store').peekAll('record-type').save() but I'm not sure if there's some better way to go about it.
I would go with:
this.get('store').findAll('users').then((users) => {
users
.filterBy('dirtyType', 'created') // filter for unsaved records
.invoke('save'); // call the save method on each model instance
});
If you return the users object you get an array of promises that you could catch with Ember.RSVP.all(), to listen for when all the users have been saved.

Checking for model update in Computed Property

I'm creating a component for rendering tables. The component is actually a set of nested components and receives a route model and config object, at the top level, then is processed within the component and passed on / iterated over in the next etc.
The final child component receives a model (representing just one row in the table) along with field name that defines which filed to display from the model.
All of this works perfectly and UI updates are bound to the model. The problem that I have is that model updates are not being pushed to the UI. Within my child component I bind to the UI element using the following:
tdVal : function(){
return this.get('data').get(this.get('details').get('field'));
}.property()
tdValUpdated : function(){
this.get('data').set(this.get('details').get('field'),this.get('val'));
}.property('tdVal'),
As you can see there is no computed property literal set for tdVal, which is why model updates are not being pushed to the UI. If I were to give this a literal value such as 'data.status' then status updates to the model are pushed to the UI.
What literal value can I use to compute on any attribute change in the model?
I've tried 'data.isUpdated', 'data.isSaving' etc. I can't use 'data.[]' as the single model, not an array of model.
OK, after much trial and error I think I've found a workaround for this. It's messy and I'm not very happy with it:
//as previous I render the the appropriate value from the model as defined
//by the passed in config object
tdVal : function(){
return this.get('data').get(this.get('details').get('field'));
}.property(),
//then detect UI changes and push to model if required
tdValUpdated : function(){
this.get('data').set(this.get('details').get('field'),this.get('val'));
}.property('tdVal'),
//Then I observe any changes to model isSaving and directly set tdVal with
//the value of the field for the current td
generalUpdateCatch: function() {
this.set('tdVal',this.get('data').get(this.get('details').get('field')));
}.observes('data.isSaving'),
I did try the following instead:
tdVal : function(){
return this.get('data').get(this.get('details').get('field'));
}.observes('data.isSaving'),
But get the error: 'Uncaught TypeError: unsupported content', no idea why? If anybody has a better solution then please post as I very much dislike these workarounds.

Ember distinguish record which is requested from server with params and without params

I'm trying to get two records from the server without knowing the ID's. The first record is requested without params and the second record with params.
It looks something like this:
model: function(){
return Ember.RSVP.hash({
cars: this.store.find('cars').then(function(car){
return car.get('firstObject');
}),
carsWithRange: this.store.find('cars', {date_from: momentLast30Days}).then(function(car){
return car.get('firstObject');
})
});
}
At the moment 'cars' and 'carsWithRange' sometimes returns the same record. I think this is happening because I use car.get('firstObject') from the cars models. Somehow I need to know that 'carsWithRange' is requested with the param 'date_from'.
Does anyone know how to fix this?
FYI I use Ember 1.12.1 with Ember Data 1.0.0-beta.15
We finally solved it in the frontend by using this.store.findQuery (with a query which doesn't make a lot of sense) instead of this.store.find. This returns the exact record which is given by the server. But yeah it feels a bit hacky.

Ember Data: How to access model values after find()

How can I access the data from a model after a find() method?
In Ember-Data 1-0-Beta I can request data from my API via user = this.store.find('user',1) but how can I get the username of the user for example? Older tutorials achieves this with user.username' or user.get('username') but it seems to be that this doesn't work anymore?
I created a fiddle: http://jsfiddle.net/3zGsC/4/ (line 21/22)
After submitting the form the username should be written to the console, but its undefined.
Basically problem is that you are trying to access properties before model is resolved. You can use then method to wait for model resolution
here is a fiddle: http://jsfiddle.net/3zGsC/5/
this.store.find('user', 1).then(
function(resolveduser) {
console.log(resolveduser.get('username')+' from then');
}
);