Duplicate records showing up in template - ember.js

I have a survey app built with Ember JS and a Firebase backend with Emberfire adapter.
Here are the relevant portions of my user model:
//app/models/user.js
export default DS.Model.extend({
name: DS.attr(),
sessionuid: DS.attr(),
surveysToTake: DS.hasMany('survey', { async: true, inverse: 'respondents' }),
surveysCreated: DS.hasMany('survey', { async: true, inverse: 'creator' }),
responseSetsSubmitted: DS.hasMany('response-set', {async: true, inverse: 'respondentid'}),
respSetSurveyLookup: DS.attr({defaultValue: function() { return []; }})
});
And my responseSet (which is a collection of responses from a user)
//app/models/response-set.js
export default DS.Model.extend({
responses: DS.hasMany('response', { async: true, inverse: 'responseSet' }),
survey: DS.belongsTo('survey', { async: true, inverse: 'responseSets' }),
respondentid: DS.belongsTo('user', {async: true, inverse: 'responseSetsSubmitted'}),
});
And the survey model looks like this:
//app/models/survey.js
export default DS.Model.extend({
title: DS.attr(),
questions: DS.hasMany('question', { async: true, inverse: 'survey' }),
respondents: DS.hasMany('user', { async: true, inverse: 'surveysToTake'}),
responseSets: DS.hasMany('response-set', { async: true, inverse: 'survey' })
});
Now, when creating a user we do something like this ...
//routes/addusers.js (in the actions hook after getting properties from the controller)
var user = store.createRecord('user', {
id: userData.uid,
name: name
});
var responseSet = store.createRecord('response-set', {
survey: survey,
respondentid: user
});
user.setProperties({
'respSetSurveyLookup': [{'surveyId': _this.currentModel.get('id'),
'respSetId': responseSet.get('id')}],
'surveysToTake': [_this.currentModel]
});
_this.currentModel.get('respondents').pushObject(user);
Ember.RSVP.all([user.save(), _this.currentModel.save(), responseSet.save()])
.then(function(){
controller.setProperties({ multipleUsers: '', showAddUsers: false});
});
The user gets added as expected. However, in my template (which shows up on the same route as the 'add users' section,) the same record shows up multiple times.
Additional info:
I'm using Ember 1.13.11 with Ember Data 1.13.11 and EmberFire
1.6.3
Refreshing the page or reloading (with a 'location.reload()' ) causes
the user records to show up as expected.
This is possibly related to an Ember data issue which appears to be now closed and an upgrade of Ember data may resolve this in the future. However, is there anything I can do in the meantime to handle this issue ?

Related

Ember 2.2 relationships always null

Can't seem to figure out why my relationships are always null.
app/models/group.js
export default Model.extend({
originalID: DS.attr('number'),
name: DS.attr('string'),
slideshows: DS.hasMany('slideshow', { async: true }),
});
app/models/slideshow.js
export default Model.extend({
originalID: DS.attr('number'),
title: DS.attr('string'),
group: DS.belongsTo('group', { async: true }),
});
Creating some data:
group = self.store.createRecord('group', {
originalID: 100,
name: 'Fake Group'
});
group.save();
slideshow = self.store.createRecord('slideshow', {
originalID: 101,
title: 'Fake Slideshow',
group: group
});
slideshow.save();
When I view the document in Pouch DB inspector group is always null. I'm following the guide on Ember's documentation page but it doesn't seem to work?
group.save() is an asynchronous operation, so you need to guarantee that it's finished before proceeding with the rest. Something like so should work:
group.save().then(g => {
let slideshow = this.store.createRecord('slideshow', {
originalID: 101,
title: 'Fake Slideshow',
group: g
});
slideshow.save();
});

A value of a model is always undefined but the json api is not

In an Ember 1.13.3 application I have this simple model :
export default DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
link: DS.attr('string'),
acquired_skills: DS.hasMany('users', { async: true, inverse: 'acquired_skills' } ),
searched_skills: DS.hasMany('users', { async: true, inverse: 'searched_skills' } )
});
And I have this route :
import Ember from 'ember'
export default Ember.Route.extend({
model: function() {
console.log(this.store.find('skill', 1).get('name'));
return this.store.find('skill');
}
});
A request is sent at /skills/1 and this is the result :
{"skill":{"id":1,"name":"Ember","description":"JS Framework","acquired_skills":[1],"searched_skills":[1]}}
In the console, 'Ember' should be written but I have undefined.
Why I have no value for the name of the skill?
I have the same behaviour for all models and attributes.
This returns a promise:
this.store.find('skill', 1)
When you do .get('name'), it hasn't finished doing the ajax request. Instead try this:
this.store.find('skill', 1).then(function(skill){
console.log(skill.get('name'));
});

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

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

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.

Value is showing up as [object Object] ember.js

I'm trying to set up the attributes to my model but having trouble when nesting objects. Here is what I have
App.Posts = DS.Model.extend({
title: DS.attr('string'),
author: {
name: DS.attr('string')
},
date: DS.attr('date'),
excerpt: DS.attr('string'),
body: DS.attr('string')
});
How am I suppose to declare the author object?
In the ember inspector when I go under data and under App.post and select one of the rows. It has a property a property App.Post with an attribute author: { name: [Object] }
here is the JS Bin link http://jsbin.com/tesozepexaqi/2/
Ember works perfectly fine without Ember Data. Let's pretend we want to do it with Ember Data:
Ember Data's Records should be flat. This means all properties are at the top level. If you have a related data that exist deeper they generally live in a different record. If you're attempting to embed the record you'll need to look into the tricky world of embedded records (Ember-data embedded records current state?). At the very least these related records must have an id defined. So here's an example of what the data returned from server should look like.
{
posts:[
{
id: '1',
title: 'My name is Django.',
author: {
id:1,
name: 'D name'
},
date: new Date('08-15-2014'),
excerpt: 'The D is silent.',
body: 'The D is silent.'
},
{
id: '2',
title: 'White horse',
author: {
id:2,
name: 'horse name'
},
date: new Date('08-15-2014'),
excerpt: 'Is what I ride.',
body: 'My horse likes to dance.'
}
]
}
Code
App.ApplicationAdapter = DS.RESTAdapter.extend();
App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
author: {embedded: 'always'}
}
});
App.Post = DS.Model.extend({
title: DS.attr('string'),
author: DS.belongsTo('author'),
date: DS.attr('date'),
excerpt: DS.attr('string'),
body: DS.attr('string')
});
App.Author = DS.Model.extend({
name: DS.attr()
});
Example: http://jsbin.com/vazada/1/edit
One other small tip, you'll not want to use globals when working with the routes, you can use modelFor to get the model from a different route.
App.PostsRoute = Ember.Route.extend({
model: function() {
return this.store.find('post');
}
});
App.PostRoute = Ember.Route.extend({
model: function(params) {
var posts = this.modelFor('posts');
return posts.findBy('id', params.post_id);
}
});
Personally, I think Ember Data is overkill. Ember works perfectly well with POJOs. If you need caching and the ability to rollback then Ember Data might be a good solution for you.
Example: http://jsbin.com/vazada/2/edit
Adjusting this example from the Ember docs like the below should work:
App.Post = DS.Model.extend({
title: DS.attr('string'),
author: DS.belongsTo('author'),
date: DS.attr('date'),
excerpt: DS.attr('string'),
body: DS.attr('string')
});
App.Author = DS.Model.extend({
post: DS.belongsTo('post')
})