I am new to EmberJs and I don't clearly understand in Ember's Adapter .I just try the ember adapter in my App.Js like that and I got this error ( Assertion failed: You tried to set adapter property to an instance of DS.Adapter, where it should be a name or a factory ) . My ember's code in App.js is :
//Store
App.Adapter = DS.RESTAdapter.extend();
App.Store = DS.Store.extend({
revision: 12,
adapter: App.Adapter.create()
});
//Models
App.Product = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
price: DS.attr('number')
});
// Products Route
App.ProductsRoute = Ember.Route.extend({
model: (function() {
return this.store.find('Product');
})
});
return App;
I think you misunderstand the way you setup and configure adapters.
//
// Application-wide adapter, everything will use this unless you override it
//
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'https://api.example.com'
});
//
// Product model, will use ApplicationAdapter
//
App.Product = DS.Model.extend({
name : DS.attr('string'),
description : DS.attr('string'),
price : DS.attr('number')
});
//
// Invoice model, will use fixtures, so specify a different adapter
//
App.InvoiceAdapter = DS.FixtureAdapter.extend({ /* options */ });
App.Invoice = DS.Model.extend({
name : DS.attr('string'),
amount : DS.attr('number')
});
//
// Routes, these should work as expected
//
App.ProductRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('product', params.id);
}
});
App.ProductsRoute = Ember.Route.extend({
model: function() {
return this.store.find('product');
}
});
App.InvoicesRoute = Ember.Route.extend({
model: function() {
return this.store.find('invoice');
}
});
return App;
Ember will know which models/routes/etc to use based on their names - see http://emberjs.com/guides/concepts/naming-conventions/ for the details.
Define the store in this way
App.Store = DS.Store.extend({
revision: 12,
adapter: App.Adapter
});
Without the create().
The main use of the adapter is to do the serialization and deserailzation of the data according to some conventions like constructing the url to post or get data from and then constructing the actual objects from the response. The Default adapter used by ember data models is the Rest adapter.
see
http://emberjs.com/guides/models/the-rest-adapter/
for more details
To use a different adapter other than the rest adapter you can specify its name like
Storm.Store = DS.Store.extend({
adapter: '_ams',
});
Try:
App.ApplicationAdapter = DS.RESTAdapter.extend();
This works for me
Related
I am a beginner in Ember and trying to implement a simple post and comment app.
I have a rails background and hence i'm using Rails API for this.
I have followed a tutorial and i'm able to save a post, fetch all its comments and delete the post. However i'm having issues in saving comment related to the post.
Following is the code for models
post.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
comments: DS.hasMany('comment')
});
comment.js
import DS from 'ember-data';
export default DS.Model.extend({
author: DS.attr('string'),
body: DS.attr('string'),
post: DS.belongsTo('post')
});
routes/post/comment/new.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return {};
},
renderTemplate() {
this.render('post.comment.new', { into: 'application' });
},
actions: {
save() {
const post = this.modelFor('post');
const newComment = this.get('store').createRecord('comment', this.currentModel);
newComment.set('post', post);
newComment.save().then(() => {
this.transitionTo('post', post);
});
},
cancel() {
this.transitionTo('post', this.modelFor('post'));
}
}
});
router.js
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('posts');
this.route('post.new', { path: 'posts/new' });
this.resource('post', { path: 'posts/:post_id' }, function() {
this.route('comment.new', { path: 'comments/new' });
});
});
export default Router;
Saving the comment is where i'm facing an issue. This is really strange but while saving the comment, the params passed to the server looks like
Parameters: {"comment"=>{"author"=>"dsa", "body"=>"asd", "post"=>"9"}}
Unpermitted parameter: post
From what i understand, the parameter should be post_id and not post. If post is being passed, then it should be object. I may be wrong of course because i don't have a clear understanding in Ember yet.
On randomly fiddling with the code, i found that if i replace the relationship in comments model from
post: DS.belongsTo('post')
to
post_id: DS.belongsTo('post')
the params passed to server are
Parameters: {"comment"=>{"author"=>"fg", "body"=>"dfs", "post_id"=>nil}}
This however doesn't actually pass the post_id as its nil.
This might be absolutely wrong and not how its supposed to work but i'm clueless.
Thanks for any help.
Create comment serializer and override keyForRelationship method like below :
keyForRelationship(key/*, relationship, method*/) {
if(key === 'post') return 'post_id';
return this._super(...arguments);
}
and the post relation should be :
post: DS.belongsTo('post')
I'm trying to add a custom property to an Ember Data Model. Specifically I want to add a property which defines the REST end point to use in an Ember Data Adapter I'm writing.
My Model is defined as such (with custom property 'endPoint'):
import DS from 'ember-data';
export default DS.Model.extend({
partner_id : DS.attr('string'),
partner_key : DS.attr('string'),
partner_name : DS.attr('string'),
created : DS.attr('string'),
status : DS.attr('string'),
type : DS.attr('string'),
endPoint : 'api_entry'
});
In my Adapter I'm trying to access the property as follows:
_buildURL: function (modelName, store, id, snapshot, requestType, query) {
var host, namespace, url;
var model = store.modelFor(modelName);
var endPoint = model.endPoint;
var endPoint2 = Ember.get(model, 'endPoint');
console.log(endPoint, endPoint2);
host = Ember.get(this, "host");
namespace = Ember.get(this, "namespace");
url = [];
if (host) {
url.push(host);
}
if (namespace) {
url.push(namespace);
}
url.push(modelName);
url = url.join("/");
if (!host) {
url = "/" + url;
}
return url;
},
In the console.log above, both endPoint and endPoint2 are undefined. I'm new to Ember and Javascript. What am I doing wrong? Is there a more 'Ember' way to do this? I don't want to use the actual REST endpoint names as my model names as they do not adhere to Ember model naming conventions.
Help much appreciated.
Your buildURL function dealing with the model class as opposed to the model instance. You need to add the property to the class:
var model = DS.Model.extend({
partner_id : DS.attr('string'),
partner_key : DS.attr('string'),
partner_name : DS.attr('string'),
created : DS.attr('string'),
status : DS.attr('string'),
type : DS.attr('string')
});
model.reopenClass({
endPoint : 'api_entry'
});
export default model;
Im using Ember Data and Ember CLI. I have a simple one-to-many relationship between two models. I'm trying to create a computed property that returns the number of items that are attached to the current model.
models/account.js
// Account model
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
notes: DS.hasMany('note', { async: true })
});
models/note.js
// Note model
import DS from 'ember-data';
export default DS.Model.extend({
body: DS.attr('string'),
date: DS.attr('number'), // unix timestamp
account: DS.belongsTo('account', { async: true })
});
controllers/account/index.js
// account/index controller
import Ember from 'ember';
export default Ember.ObjectController.extend({
oldNotesCount: function() {
var notes = this.get('notes');
console.log('=-=', notes.length); // undefined *****
return notes.length;
}.property('notes.#each')
});
How come notes.length is undefined?
I've simplified this example... I can't use {{notes.length}} in my situation as there will be more calculations going on—this is just the first step.
You marked notes association as async so this.get('notes') returns a promise. Promises do not have length property hence getting undefined.
To get data in an async association call then on returned promise with a function as argument. Association data will be passed to that function as first argument.
export default Ember.ObjectController.extend({
oldNotesCount: function() {
var _this = this;
this.get('notes').then(function(notes){
_this.set('oldNotesCount', notes.get('length');
});
return null;
}.property('notes.#each')
});
I'm pretty new to Ember.js and am building an app to pick up some Ember chops. I wanted to use a computed property in one of my models as a route but it seems something isn't working correctly. I'm using FIXTURES by the way.
What I'm trying to achieve is /peeps/john-smith instead of /peeps/1
I've got my model setup like this:
App.Peep = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
slug: function(){
this.get('firstName').toLowerCase() + '-' + this.get('lastName').toLowerCase();
}.property('firstName', 'lastName')
});
My router setup is like this:
App.Router.map(function(){
this.resource('peep', { path: '/peeps/:peep_slug'});
});
App.PeepRoute = Ember.Route.extend({
model: function(params){
return this.store.find('peep', params.peep_slug);
},
serialize: function(model){
return { peep_slug: model.get('slug') };
}
});
When I navigate to /peeps/john-smith in the browser, I get this warning in my console You made a request for a peep with id john-smith.
Is there something I'm missing?
By default it searches by id param, so you could either change the adapter to make it search by slug or try to add id as Ember.computed.alias('slug').
I've set up an ember.js client with ember-data as persistance handler.
Fetching all records from the DB works fine with this code:
router.js
App.ProjectsRoute = Ember.Route.extend({
model: function() {
return this.store.find('project');
}
});
But adding a new record doesn't work correctly with this code. It's only added to the model and not persisted.
index.html (example)
{{input type="text" id="newTitle" value=Title}}
<button class="small" {{action 'createProject'}}><i class="icon-plus-sign"></i></button>
Controller.js
App.ProjectsController = Ember.ArrayController.extend({
actions: {
createProject: function () {
var project = this.store.createRecord('project', {
project_number: this.get('newProject_number'),
title: this.get('newTitle'),
client: this.get('newClient'),
comment: this.get('newComment'),
xmlfile: this.get('newXmlfile')
});
this.set('newProject_number', '');
this.set('newTitle', '');
this.set('newClient', '');
this.set('newComment', '');
project.save();
}
}
});
models.js
App.Project = DS.Model.extend({
title: DS.attr('string'),
client: DS.attr('string'),
comment: DS.attr('string'),
project_number: DS.attr('string'),
});
app.js
window.App = Ember.Application.create();
App.store = DS.Store.extend({
adapter: DS.RESTAdapter,
});
DS.RESTAdapter.reopen({
namespace: 'api/index.php',
headers: {
"API_KEY": "secret key",
"ANOTHER_HEADER": "Some header value"
}
});
Framework versions
Ember : 1.2.0;
Ember Data : 1.0.0-beta.5+canary.e120006;
Handlebars : 1.1.2;
jQuery : 2.0.3;
What have I missed to configure? There's no error in the console however.
REST-Api works well with curl.
The problem is the structure of the JSON "POST"ed towards the API:
Sent:
{project: {client: "test",comment: "test",project_number: "test",title: "test"}}
Expected by API-Backend:
{client: "test",comment: "test",project_number: "test",title: "test"}
I wonder where I could have found the information how ember-data build it's requests. (For further development)