How to specify async belongsTo/hasMany relationships in emberfire/emder-data? - ember.js

I am very new at Ember/ED/EmberFire so apologies if this is a trivial question. I am able to save records to Firebase but I am unable to specify relationships to those records in my controller. I am using
DEBUG: Ember : 1.10.0
DEBUG: Ember Data : 1.0.0-beta.12
DEBUG: Firebase : 2.2.3
DEBUG: EmberFire : 1.4.3
DEBUG: jQuery : 1.11.2
I have a model as such:
var Patient = DS.Model.extend({
lastName: DS.attr('string'),
firstName: DS.attr('string'),
encounters: DS.hasMany('encounter', {async: true})
});
var Encounter = DS.Model.extend({
dateOfEncounter: DS.attr('string'),
patient: DS.belongsTo('patient', {async: true})
});
I am simply trying to specify the patient that my newly created encounter object is associated with. This is my controller:
actions: {
registerEncounter: function() {
var newEncounter = this.store.createRecord('encounter', {
dateOfEncounter: this.get('dateOfEncounter'),
patient: this.store.find('patient', '-Jl8u8Tph_w4PMAXb9H_')
});
newEncounter.save();
this.setProperties({
dateOfEncounter: ''
});
}
}
I can successfully create the encounter record in Firebase, but there is no associated patient property. All I get is
https://github.com/firebase/emberfire/issues/232

this.store.find('patient', '-Jl8u8Tph_w4PMAXb9H_') returns a promise.
Try this:
this.store.find('patient', '-Jl8u8Tph_w4PMAXb9H_').then(function(pat) {
var newEncounter = this.store.createRecord('encounter', {
dateOfEncounter: this.get('dateOfEncounter'),
patient: pat
});
newEncounter.save();
});

Related

Error for one hasMany but not another. Makes no sense

I have a model "Group" that has some hasMany relationships "members" and "links". I have a controller that adds a new group but i get the following error on save
"Assertion Failed: A App.Group record was pushed into the store with the value of links being '{}', but links is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer."
I can fix this by returning an empty links array in the response json but i don't necessarily want this included and i don't understand why i get this error for links but not for members as that isn't included in the response either.
App.AddGroupController = Ember.ObjectController.extend({
needs: ['application'],
actions: {
submitForm: function(){
var self = this;
var model = this.get('model');
self.send('showLoading', 'Saving');
model.save().then(function(){
self.send('hideLoading');
//Go to the groups list
self.transitionToRoute('groups');
},function(error){
self.send('hideLoading');
console.log(error);
//Must supply reject callback, otherwise Ember will throw a 'backend rejected the commit' error.
});
}
}
});
App.AddGroupRoute = App.AuthenticatedRoute.extend({
model: function(){
return this.store.createRecord('group');
}
});
App.Group = DS.Model.extend({
title: DS.attr('string'),
description: DS.attr('string'),
members: DS.hasMany('groupMember'),
links: DS.hasMany('groupLink'),
});
App.GroupLink = DS.Model.extend({
title: DS.attr('string'),
link: DS.attr('string'),
});
App.GroupMember = DS.Model.extend({
first_name: DS.attr('string'),
last_name: DS.attr('string'),
email: DS.attr('string'),
profile_picture: DS.attr('string'),
});
Response from save:
{
"group":{
"id":26,
"title":"Test Group",
"description":"Dummy group description",
}
}
Im using:
Ember : 1.9.1
Ember Data : 1.13.14

Error while processing route error in ember.js with ember-data

I'm trying to create an app using ember.js and ember-data, using the following versions:
DEBUG: Ember : 1.7.0
DEBUG: Ember Data : 1.0.0-beta.9
DEBUG: Handlebars : 1.2.1
DEBUG: jQuery : 2.1.0
I'm using the RESTAdapter to connect to an api I wrote using node.js.
As soon as I load the app I keep getting the following error:
Error while processing route: students undefined is not a function TypeError: undefined is not a function
at http://localhost:9000/scripts/vendor/ember-data.js:12006:34
at tryCatch (http://localhost:9000/scripts/vendor/ember.js:45818:16)
at invokeCallback (http://localhost:9000/scripts/vendor/ember.js:45830:17)
at publish (http://localhost:9000/scripts/vendor/ember.js:45801:11)
at http://localhost:9000/scripts/vendor/ember.js:29069:9
at DeferredActionQueues.invoke (http://localhost:9000/scripts/vendor/ember.js:634:18)
at Object.DeferredActionQueues.flush (http://localhost:9000/scripts/vendor/ember.js:684:15)
at Object.Backburner.end (http://localhost:9000/scripts/vendor/ember.js:147:27)
at Object.Backburner.run (http://localhost:9000/scripts/vendor/ember.js:202:20)
at apply (http://localhost:9000/scripts/vendor/ember.js:18382:27)
Here's the code I'm using (loaded in the same order I pasted it):
app.js
var App = window.App = Ember.Application.create({
LOG_ACTIVE_GENERATION: true,
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: false,
LOG_VIEW_LOOKUPS: true
});
store.js
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000',
serializer: DS.RESTSerializer.extend({
primaryKey: function(type) {
return '_id';
},
serializeId: function(id) {
return id.toString();
}
})
});
models/student.js
App.Student = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
nationality: DS.attr('string'),
createdAt: DS.attr('date')
});
routes/app_route.js
App.StudentsRoute = Ember.Route.extend({
model: function() {
return this.store.find('student');
}
});
router.js
App.Router.map(function () {
this.resource('students', {path: '/'});
});
And the following is the response of the API:
{
students: [
{
nationality: "Lorem",
lastName: "Doe",
firstName: "John",
_id: "53f87200f3750319b4791235",
createdAt: "2014-08-23T10:50:40.661Z"
},
{
nationality: "Lorem",
lastName: "Doe",
firstName: "John",
_id: "53f87299f3750319b4791234",
createdAt: "2014-08-23T10:50:40.661Z"
}
]
}
It looks like the store is not loading the data from the API, but the JSON data format looks fine. Any idea of what could be wrong?
Thanks!
So after searching more on Stack Overflow, I've figured out that the serializer has now to be in a separate class than the RESTAdapter, so the working code is the following:
store.js
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000'
});
App.ApplicationSerializer = DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
Here's an updated answer for people using ember-cli.
ember g adapter application #=> creates app/adapters/application.js
ember g serializer application #=> creates app/serializers/application.js
In app/adapters/application.js:
import DS from 'ember-data';
export default DS.RestAdapter.extend({
host: 'http://localhost:3000'
});
In app/serializers/application.js:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
I was getting this error, and it had nothing to do with any of the usual suspects.
In coffeescript, I had started defining a model.
App.Cost = DS.Model.extend
amount: DS.attr 'number'
active: DS.attr 'boolean'
To create a second model, I c/p my first model in and deleted the attributes:
App.Cost = DS.Model.extend
The went back and tried to run a seemingly unrelated model
localhost:3000/products
Which resulted in the error
Error while processing route: products.index
Simply making sure my model was named correctly solved the error:
App.Cost = DS.Model.extend(...)
App.Price = DS.Model.extend(...) <- instead of repeating the Cost model
This was re-produceable, so I thought it might be helpful to others.

TypeError: Unable to set property 'store' of undefined or null reference in ember.js

Below is the code I am using to get data from web API. But every time I try to retrieve data I get same error: Unable to set property 'store' of undefined or null reference in ember.js.
/// <reference path="Lib/ember.js" />
/// <reference path="Lib/ember-data.js" />
var App = Ember.Application.create();
Ember.onerror = function(e) {
alert(e);
};
App.ApplicationAdapter = DS.RESTAdapter.extend({
namespace: 'api'
});
App.store = DS.Store.create({
adapter: App.ApplicationAdapter
});
App.Product = DS.Model.extend({
ID: DS.attr("int"),
Name: DS.attr('string'),
Category: DS.attr('string'),
});
App.ApplicationRoute = Ember.Route.extend({
model: function() {
{{debugger}}
var store1 = this.get("store")
var k = store1.find('product', 1)
return k;
}
});
Your problem is with the returned json from the server. You need to return the following object:
{
product: {
// key value
}
}
If you want to use the DS.RESTAdapter defaults, you can just return the data in that format:
{
product: {
id: 1,
name: 'some name',
category: 'some category'
}
}
And change your model mapping to:
App.Product = DS.Model.extend({
name: DS.attr('string'),
category: DS.attr('string'),
});
If you want to use the capitalized properties like Name, Category. You will need to override some methods of DS.RESTAdapter. If your endpoing doesn't match this format.
Other error is that doesn't exist a DS.attr('int') just DS.attr('number'). But you can remove the id mapping, since is created by default.
This is a jsfiddle with this working http://jsfiddle.net/marciojunior/W5LEH/
Ensure that you are using last versions of Ember.js and Ember-Data.
This is how you define a store for you application:
App.Store = DS.Store.extend({
adapter: App.ApplicationAdapter
});
Note the capital S in Store and extend instead of create.
See Ember-Data Guide

Failed to get child records without embedded property (JSBIN inside)

I would get the records of my field children. Here the code:
App.User = DS.Model.extend({
name: DS.attr('string'),
online: DS.attr('boolean')
});
App.List = DS.Model.extend({
name: DS.attr('string'),
children: DS.hasMany('App.User'),
online: function() {
var users = this.get("children");
return users.reduce(0, function(previousValue, user){ // no record founds
return previousValue + user.get("online");
});
}.property("children.#each.online")
});
But App.List.find(1).get('online') returns no record. (For some reason I cannot specify that App.List.children contains many records, of type App.Users, as embedded records).
Here is the fiddle: JSBIN and it's output
How I can solve my issue?
Define the embedded Model on your Adapter map:
App.List = DS.Model.extend({
name: DS.attr('string'),
users: DS.hasMany('App.User'), //use "users" as the property name to mantain ember's naming conventions
...
});
App.Adapter = DS.RESTAdapter.extend();
App.Adapter.map('App.List', {
users: {embedded: 'always'} //you can use `always` or `load` which is lazy loading.
});
App.Store = DS.Store.extend({
revision: 12,
adapter: App.Adapter.create()
});
Hope it helps

How to create record with an hasMany and belongsTo association? [EmberJS]

I'm working with Ember with Rails Backend
Ember.VERSION : 1.0.0-rc.3 ember.js:349
Handlebars.VERSION : 1.0.0-rc.3 ember.js:349
jQuery.VERSION : 1.9.1
I have three models
App.SocialNetwork = DS.Model.extend({
name: DS.attr('string'),
actors: DS.hasMany('App.Actor'),
relations: DS.hasMany('App.Relation'),
});
App.Actor = DS.Model.extend({
name: DS.attr('string'),
x: DS.attr('number'),
y: DS.attr('number'),
social_network: DS.belongsTo('App.SocialNetwork'),
relations: DS.hasMany('App.Relation'),
isSelected: function () {
return false;
}.property(),
});
App.Relation = DS.Model.extend({
name: DS.attr('string'),
actors: DS.hasMany('App.Actor'),
social_network: DS.belongsTo('App.SocialNetwork'),
});
And Inside my RelationsController I want to create a new instance of Relation
I tried to do it like this
App.RelationsController = Ember.ArrayController.extend({
currentRelation: null,
add: function () {
// get the selected actors
var actors = this.get('socialNetwork.actors').toArray().filter(function (element) {
return element.get("isSelected") == true;
});
// create the new relation with those actors
var newRelation = App.Relation.createRecord({
actors: actors,
name: "New Relation",
});
this.set('currentRelation', newRelation);
this.get('content').pushObject(newRelation);
this.get('store').commit();
},
});
But the relation is not being stored, and I debug the new record created and it doesn't have any actors or social network associations.
What I'm doing wrong or not doing here?
Thanks in advance for your help
PS: by the way, the socialNetwork and actors load correctly
It looks like you forgot belongsTo side of the relationship. Add
relation: DS.belongsTo('App.Relation')
to your App.Actor model.