How to set an API url for Ember Model - ember.js

I'm using Ember Model and I would like to set up a URL prefix for all my models, instead of prepending them on each model like this:
App.MyModel = Ember.Model.extend({
id: attr(),
myAttr: attr()
});
App.MyModel.reopenClass({
url: ajaxUrl + '/some/obscure/path'
});
I'm aware I could probably override Ember.Model so that url defaults to ajaxUrl, but then if I want to set it to something other than default, like in the example above, I would have to prepend it.
If this is not possible, is there a recommended way to set a default url?

The best solution I came up with is to extend Ember.RESTAdapter itself.
Ember.RESTAdapter = Ember.RESTAdapter.extend({
ajaxSettings: function(url, method) {
return {
url: ajaxUrl + url,
type: method
};
}
});
App.MyModel = Ember.Model.extend({
id: attr(),
myAttr: attr()
});
App.MyModel.reopenClass({
adapter: Ember.RESTAdapter.create(),
url: '/some/obscure/path'
});
Because that's the adapter I use for my models. I guess it's not ideal, but it works ok.

Related

ember data not saving foreign key, sent as null

My ember app is not sending my foreign key to the back-end.
I have a table called issues which is has a related table called categories
My model is:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
category_id: DS.belongsTo('category'),
description: DS.attr('string')
});
My route is:
import Ember from 'ember';
export default Ember.Route.extend({
model: function(){
return this.store.findAll('issue');
},
actions: {
create: function(){
var issue = this.store.createRecord('issue');
issue.name = this.get('controller').get('newName');
issue.description = this.get('controller').get('newDescription');
issue.category_id = parseInt(this.get('controller').get('newCategory'));
//debugger;
console.log(issue);
issue.save();
},
...
other actions
...
}
}
});
the console.log from above looks like the category_id is getting set correctly:
category_id: 3
description: "foobar"
name: "test"
However my JSON payload that gets sent to the backend looks like:
{"issue":{"name":"test","description":"foobar","category_id":null}}
I tried stepping through by adding a custom serialiser in app/serializers/application.js
export default DS.RESTSerializer.extend({
...
serialize: function(snapshot,options){
console.debug('options='+options);
debugger;
var json = this._super(snapshot, options);;
return json;
}
...
});
But I got lost in all the super calling super indirection.
The snapshot.record has category_id: 3, but the json coming back from the this._super() call has category_id: null
options has includeID:true
Any clues will be much appreciated ...
Ember : 2.0.2
Ember Data : 2.0.0
Your model definition is wrong, when dealing with relationships you define them just as you would define any other attribute, there is no need to use _id.
export default DS.Model.extend({
name: DS.attr('string'),
category: DS.belongsTo('category'),
description: DS.attr('string')
});
As for the creation you should always use setters/getters when dealing with ember objects:
create: function() {
var issue = this.store.createRecord('issue', {
name: this.get('controller').get('newName'),
description: this.get('controller').get('newDescription'),
category: this.get('controller').get('newCategory') // assuming new category is a DS.Model instance of category
});
issue.save();
}
If you wish to stick to the syntax you have you would use issue.set('name', this.get('controller').get('newName')), from the looks of your code it seems you are going about this in the wrong way.
You should have a this.route('new') nested under your issues route, that way you wouldn't have to use the controller to store information.
You would simply set the model of the new route to:
model: function() {
return this.store.createRecord('issue');
}
Your template would make use of the input helpers like so:
{{input value=model.name}} and your action would just get the currentModel and call .save().

Emberjs - how to remove pluralization of URLs?

I am building an emberjs app and I want to call my REST API for results. I have this code:
App.Post = DS.Model.extend();
App.PostAdapter = DS.RESTAdapter.extend({
namespace: 'api/v1',
host: 'http://myapp.com'
});
And in the controller I have this
post: this.store.find('post')
The problem is that it always calls with "s" added in the end, for example - http://myapp.com/api/v1/posts
How do I remove the plural form from these calls?
You need to override the pathForType method in your adapter.
App.PostAdapter = DS.RESTAdapter.extend({
pathForType: function(type) {
var camelized = Ember.String.camelize(type);
return Ember.String.singularize(camelized);
}
});
var inflector = new Ember.Inflector();
inflector.singularize('posts');
Ember put 's' automatically. You need to force it to use singular. Above code tells Ember to request to myapp.com/post when you call this.store.find('post'); otherwise default behaviour will try to send request to myapp.com/posts
I had same issue once upon a time. I could not even found a way to set this behaviour globally. I have repeated this code ( inflector.singularize('posts'); ) for every store.

How can I fetch a single model from the server

How can I fetch a single model from the server using Ember Data?
For example, I have url for my server api localhost:8080/rest/setting, and respond is JSON object
{
"siteName": "lala",
"siteUrl": "blabla"
}
In the result I want to use this model for rendering in my template.
I'm going to assume you meant to say "...can I fetch a single model from the server without using Ember Data", in which case of course you can! Just use jQuery to get your data. For example:
App.ExampleRoute = Em.Route.extend({
model: function (params) {
return Ember.$.ajax({
type: "GET",
url: 'localhost:8080/rest/setting',
dataType: 'json'
});
}
App.Setting = DS.Model.extend({
sitename: DS.attr()
});
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:8080', // this isn't necessary, since it'll use the current server's host
namespace: 'rest' // this is appended to your current web server host http://server/rest
});
App.Router.map(function() {
this.resource('foo', {path:'/:foo_id'});
});
App.FooRoute = Em.Route.extend({
model: function(params){
// if param.foo_id is 1 then
// this would be http://localhost:8080/rest/setting/1
return this.get('store').find('setting', params.foo_id);
}
});
your JSON should come back in this format:
{ setting: { "siteName": "lala", "siteUrl": "blabla" } }
If you want it to be in a different format you need to use a serializer and massage the data into the format Ember is expecting: https://github.com/emberjs/data/blob/master/TRANSITION.md

Ember js how to use the BasicAdapter

I am looking for a guide that will help me understand syncing models in ember. I tried to use the RestAdapter on the latest build and I am getting an error. So I decided to use the BasicAdapter based on stabilizing ember data on the ember js site.
Here is my model:
App.Accounts = DS.Model.extend({
name:DS.attr('string')
,date:DS.attr('date')
})
Here is where I declare the sync functions for the model.
App.Accounts.sync = {
list: function() {
$.ajax({
type: 'POST',
cache: false,
url: contextPath + 'account/list',
success: function(data) {
this.load()
},
error: function(jqXHR, textStatus, errorThrown) {
},
async: false
});
}
}
I am calling the list function in a setup controller:
App.TestRoute = Ember.Route.extend({
setupController:function(){
App.Accounts.list()
}
})
The function does not execute. What is the correct way to call sync functions in an ember application? Also, I could use a blog/article on this topic.
Thanks!
Have you checked out Ember Model it gives you a basic adapter without having to use EmberData.
Erik has a tutorial at embercasts.com you may need to signup to be beta user.
var attr = Ember.attr;
App.User = Ember.Model.extend({
id: attr(),
name: attr()
});
App.User.url = "/users";
App.User.adapter = Ember.RESTAdapter.create();
var newUser = App.User.create({name: "Erik"});
newUser.save(); // POST to /users.json
var existingUser = App.User.find(1); // GET /users/1.json
existingUser.set('name', 'Kris');
existingUser.get('isDirty'); // => true
existingUser.save(); // PUT /users/1.json
Cheers

DS.Model url not working in ember.js

I'm very, very, very new to Ember :-)
I have a DS.Model where I want to force the extension with .json, for retrieving the data from a Rails Server.
The url from the Server is working, and for I can see in the browser's debugger, the url is not what it's specified in the DS.model url
var App = Ember.Application.create();
App.store = DS.Store.create({
adapter: DS.RESTAdapter.create({url: 'http://127.0.0.1:3000'}),
revision: 8
});
App.Expedient = DS.Model.extend({
url: 'expedients/%#.json',
procedencia: DS.attr('string'),
interessat_nom: DS.attr('string'),
data_signatura_provisional: DS.attr('date')
});
Fetch the expedient manually:
var model2 = App.store.find(App.Expedient, 125000);
Output console:
OPTIONS http://127.0.0.1:3000/expedients/125000 404 (Not Found)
I would like to be this url like this:
http://127.0.0.1:3000/expedients/125000.json
Also I've tried to really change the DS.Model url with another different name like this:
App.Expedient.reopenClass({
url: 'mockurl/%#.json'
});
But the browser's console has the same 'url' as before, I don't know why Ember-Data is not getting the model's url.
thanks!
regards,
ps. I'm aware of the Access-Control-Allow-Origin CORS problem when testing Ajax from two origins
github isn't working right now, for some reason, so I can't look at the source for ember, but I think you can do something like this:
var adapter = DS.RestAdapter.extend({
buildURL: function(record, suffix) {
var s = this._super(record, suffix);
return s + ".json";
})
});
You'll need to plug this your store instead of the default rest adapter.
I just tried this with my RESTAdapter subclass and it's working:
App.WORESTAdapter = DS.RESTAdapter.extend({
...
buildURL: function(record, suffix){
return this._super(record, suffix) + ".json";
}
})
Since you are working with a rails back end would it be easier to adapt your API to the same conventions Ember.data expects? so in your expedientsController#show action:
def show
#expedient = Expedient.find(params[:id])
render json: #expedient
end
As long as your controller is returning the JSON structure Ember expects it should map to your DS.Model see: this ember guide.