Ember Data: How to access model values after find() - ember.js

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');
}
);

Related

Find the class name of a relation from the instance of a model in ember JS

I have foo an instance of the ember-data model thing. thing.js has the following property :
owner: DS.belongsTo('user')
If I have foo with an empty owner, how can I, with only foo and the 'owner' string, retrieve the value 'user' representing the model of the owner relation?
EDIT: I want to allow my select-relation component to works with relations where the name is different from the class name
It sounds like you have some work to do to finish setting up your relationships. Have a read through this page of the guides.
If the relationships are set up correctly, to get the associated user, you should be able to do foo.owner. This assumes that users are already present in the store. I recommend using the Ember Inspector browser plugin to debug the relationships.
This looks like a use case for typeForRelationship.
In your example you should be able to do something like
store.modelFor('thing').typeForRelationship('owner', store);
If you don't like that approach you can use the belongsTo reference API, where you use the meta data from the relationship to get the type
foo.belongsTo('owner').type
The only thing with that approach is that the type property may not be public API and possible (though unlikely) to change at some point.
It seems I can do the following :
this.get('model').get('_internalModel._relationships.initializedRelationships.'+this.get('relation')+'.relationshipMeta.type')
model being an instance and relation the string of the relation name, it correctly return the model of the relation.
EDIT : a better solution not using private API courtesy from the ember discord :
function getRelatedModelName(record, relationName){
let ParentModelClass = record.constructor;
let meta = get(ParentModelClass, 'relationshipsByName').get(relationName);
return meta.type;
}

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.

Dynamically add js object to model array in 1.13

I have the following code:
var msg = this.store.createRecord({text:'first title', createdAt: "2015-06-22T20:06:06+03:00" })
this.get('model.content').pushObject(msg);
msg.save();
We create new record. Then push in it to the model to display. It worked perfectly in 1.9 version but after upgrading it to the newest 1.13 it breaks and shows this error:
TypeError: internalModel.getRecord is not a function
after some researches I came out to this solution
this.get('messages.content').unshiftObject(message.internalModel);
and it partially help. Now I have two problems:
I'm not confident if using private ember data api is a good idea
I have an annoying delay between adding record to the model and
rendering it on the screen. More than that if I don't call
msg.save(); the record isn't rendered. So as far as I understood it
waits until we have response from server and only then renders it.
But I need opposite behaviour - I need to show the record first and
then save it(showing the saving state for the user), this way user
thinks that everything goes extrimely fast.
One possible solution without resorting to private API is to use toArray() (github issue):
var array = this.get('messages').toArray()
array.addObjects(this.get('messages'))
array.addObject(msg)
this.set('messages', array)
Before 1.13:
this.get('content').pushObjects(messages);
After 1.13:
messages.forEach(functio(message) {
this.get('model.content').pushObject(message._internalModel);
});
I would make all return models to array then, add array to this array
setPeople:function(){
this.set('people',this.get('content').toArray())
}.observes('content')
then, find more person models, to array
getMoreUsers(){
var self = this;
this.set('offset', this.get('offset')+1);
self.store.findAll('person').then(function(people){
self.get('people').pushObjects(people.toArray());
});

Creating vs Modifying in backbone.js

This is my first application using backbone and REST API, I'm a bit confused with some specific scenarios when it comes to creating-editing. So if the model exits on server, it will EDIT, if it doesn't it CREATES.
When I pass on a unique identifier in my model, it knows it exits, but if I pass a combination of existing data without a unique identifier it always assumes it should CREATE. I'm not sure if this should be solved on client side or server.
For instance:
var exportationMod = new Backbone.Model({ 'asset': '/api/v1/asset/'+this.assetID+'/', 'export_configuration': '/api/v1/exportconfiguration/'+this.model.get('id')+'/' });
exportationMod.url = '/api/v1/exportation/';
exportationMod.save();
OK so the server is running with django + tastypie. Should this be validated by the client by first making an extra query, on the server (maybe there is a way of setting a combination of unique keys like mysql), or is there another setting I can tweak so it edits instead of creating?
If you pass data to the server without some unique id, how would the server know what to update?
If it makes sense for your situation, you can override isNew() in your model.
var MyModel = Backbone.Model.extend({
idAttribute: 'somethingUnique',
url: '/api/v1/exportation/',
isNew: function(){
// return true if you want create (POST),
// return false if you want update (PUT)
}
});
By default it looks like this (with the above model, this.id would be the idAttribute value above):
// A model is new if it has never been saved to the server, and lacks an id.
isNew: function() {
return this.id == null;
},
If you want to edit something that already exists on the server, you should just fetch it first before editing/saving it. Also, if there is some unique id that is not called 'id' you can override that on the model as well (see above).

Django: How to access the model id's within an AJAX script?

I was wondering what is the correct approach,
Do I create HiddenInput fields in my ModelForm and from the
View I pass in the primaryKey for the models I am about to edit into
the hiddenInput fields and then grab those hiddenInput fields from
the AJAX script to use it like this?
item.load(
"/bookmark/save/" + hidden_input_field_1,
null,
function () {
$("#save-form").submit(bookmark_save);
}
);
Or is there is some more clever way of doing it and I have no idea?
Thanks
It depends upon how you want to implement.
The basic idea is to edit 1. you need to get the existing instance, 2. Save provided information into this object.
For #1 you can do it multiple ways, like passing ID or any other primary key like attribute in url like http://myserver/edit_object/1 , Or pass ID as hidden input then you have to do it through templates.
For #2, I think you would already know this. Do something like
inst = MyModel.objects.get(id=input_id) # input_id taken as per #1
myform = MyForm(request.POST, instance=inst)
if myform.is_valid():
saved_inst = myform.save()
I just asked in the django IRC room and it says:
since js isn't processed by the django template engine, this is not
possible.
Hence the id or the object passed in from django view can't be accessed within AJAX script.