Creating vs Modifying in backbone.js - django

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

Related

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.

Sitecore return field "Fields" with zero count in SocialProfiles

Sitecore return field "Fields" with zero count in SocialProfiles, but this fields in social network really exist. How I can get need fields?
var socialProfileManager = new SocialProfileManager();
var twitterNetwork = allProfiles.FirstOrDefault(x => x.NetworkName == "Twitter");
if (twitterNetwork.Fields.Count != 0) //Dicitionary "Fields" is empty here
{
...
}
I had a similar situation where I was trying to retrieve the fields and dealing with the zero field count. Take a look at this post: https://stackoverflow.com/a/30519345/4897782
Specifically, my issue was resolved when I passed false as the second parameter in the base login method. The default true parameter attempts to update the profile asynchronously, making it unavailable during my attempts to do what you are doing.
To be able to override the parameter though, I had to deviate from the standard out of the box login controls and implement my own version of what happens when you click login. It's pretty simple though. Take a look at the post and hopefully that resolves your issue.

Can i hide the query params from the URL?

In my Ember.js Application, I am dealing with query params for list updates. I have one strange use case, in which I don’t the URL to be updated with certain query params. How can I achieve this?
I assume you want to reload your model with parameters that are different than the ones in your application route? And you keep your application route parameters synced using queryParams?
In your route's model function you can filter your model data by the same query params (that appear in the address bar) but you can add some logic that extracts additional parameters either from the controller or other place and these parameters the data fetching query. Example:
model: function(queryParams) {
var params = queryParams;
params.additional_filter = this.controllerFor('mycontroller').get('additional_filter');
return this.store.find('mymodel', params);
}
Also if you want to explicitly reload the model you will need to call Router.refresh() function.

How can I load a model and immediately have access to it

Say that when I load the page I include a json hash of the current user's info
in an injection I load the info:
user_data = JSON.parse(user_json)
App.Model.load(user_data['id'], user_data)
container.typeInjection('controller', 'currentUser', 'controller:currentUser')
App.set('currentUserController', controller)
But I'd like to set the value of that currentUserController right here as well - App.Model.load doesn't return the actual model instance!
to get it, I need to run App.Model.find(user_data['id']) and because this is done at start up, it seems that ember-model always ends up querying the database for this model rather than using the json I've preloaded.
Because I use this model in the startup of my app I can't defer the loading - how can I get access to the loaded model without needing to do an ajax request?
This answer might help you: https://stackoverflow.com/a/16254735/437019
And as for loading from json, try:
var store = DS.get("defaultStore");
var adapter = store.adapterForType(App.User);
var id = USER_ID_HERE;
adapter.didFindRecord(store, App.User, YOUR_JSON_DATA_HERE, id);
var user = App.User.find(id);
I'm using Ember-model so this might be different for ember-data.
The trick is to use create (not create record!) to make an empty version of the model, and then populate it with the instance's load call. IE
user = App.User.create()
user.load(user_data['id'], user_data)
That will both load the data into the version you have, and correctly call didLoad to ensure it's in the store.

Update URL after model is modified

I have a route like this "loans/:loan_id", from a link I redirect to this URL and send an unsaved Loan object as model, so the id is null, which results in the url being "loans/null", however I then save the model and it gets an ID from the server, but how can I update the URL so that it shows the new ID instead of null?
Thanks.
I assume you have a LoanNewController or something similar. Then I further assume that you are trying to transition to the new created loan object directly after you have created it, this will show an id of null since the create loan action is async and you have to wait for the loan to be created on the backend before you do the transition, so in order for it to work you could do the following:
App.LoanNewController = Ember.ObjectController.extend({
saveLoan: function() {
...
this.get('store').commit();
},
...
transitionAfterSave: function() {
if(this.get('content.id')) {
this.transitionToRoute('loan', this.get('content'));
}
}.observes(content.id)
The added observer will observe the content.id and when it is set (when the server call has returned) the transitionAfterSave will be invoked and the transition will get the content passed to it with the correct id in place.
This answer is based mainly on assumptions, since you didn't reveal that much code, but you get the point I guess.
Hope it helps.