duplicated data when navigating without reloading page using ember-data - ember.js

I'm using ember.js 1.0.0-pre4, ember-data revision 11.
I have the following model:
App.DbProcess = DS.Model.extend({
pid: DS.attr('number'),
backendStart: DS.attr('string'),
transactionStart: DS.attr('string'),
queryStart: DS.attr('string'),
stateChange: DS.attr('string'),
waiting: DS.attr('boolean'),
state: DS.attr('string'),
query: DS.attr('string')
})
With the following route:
App.HomeDbProcessesRoute = Ember.Route.extend({
model: function() {
return App.DbProcess.find();
}
})
I then have a template which uses {{#each controller}}{{/each}} to render all the processes retrieved. However if I navigate to other pages (without reloading the page) and returning back to the processes page, the processes will be retrieved again and the duplicates are rendered on page.
EDIT: I also tried this, but it didn't work:
DS.RESTAdapter.map('App.DbProcess', {
primaryKey: 'pid'
})

I had the same issue now and here is my little hot-fix:
{{#if id}}
<div>
{{title}}
</div>
{{/if}}
In the template I render item from store only if it has id set (only those are coming from databse). But You propably solved it already!
(using revision 12)

Turns out you can do something like this to customize the primary key globally
App.Adapter = DS.RESTAdapter.extend({
url: document.location.protocol+'//url-api.com',
serializer: DS.RESTSerializer.extend({
primaryKey: function(type) {
// If the type is `BlogPost`, this will return
// `blog_post_id`.
var typeString = (''+type).split(".")[1].underscore();
return typeString + "_id";
}
})
})

Related

Unexpected text being rendered by Ember

I have models
// models/group
export default DS.Model.extend({
parent: DS.belongsTo('parent'),
items: DS.hasMany('item', {async: true}),
quantity: Ember.computed.sum('items.#each.quantity'),
});
// models/item
export default DS.Model.extend({
...
quantity: DS.attr('number')
});
And in my template (with controller.model set to parent) I try to render
{{#each group}}
{{quantity}}
{{/each}}
and expect a list of numbers, but instead what's rendered is a list of text like <spa#model:item::ember1036:165>
I'm guessing that the async promise is only resolved after rendering, but then why does it not update?
I don't believe sum will pull properties from each item in a collection. I believe it has to be a collection of numbers.
quantities: function(){
return this.get('items').getEach('quantity');
}.property('items.#each.quantity'),
quantity: Ember.computed.sum('quantities'),

Ember computed property to return first X number of items from list

I have a one-to-many relationship (using Ember Data). All I want to do is list the first N number of items from that relationship in an overview (index) template. I'm trying to use the Array.slice method but it doesn't seem to return anything at all.
Here's what I have right now:
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({
firstNotes: function() {
return this.get('notes').slice(0,2);
}.property('notes')
});
templates/account/index.hbs
{{!-- this lists all the associated `Notes` --}}
{{#each notes}}
{{date}}<br>
{{body}}
{{/each}}
{{!-- this doesn't list anything!!?? --}}
{{#each firstNotes}}
{{date}}<br>
{{body}}
{{/each}}
I figured this out just as I was about to post it so I figured I'd answer it...
All I was missing was a #each in the computed property dependency. So it works as expected with this:
firstNotes: function() {
return this.get('notes').slice(0,2);
}.property('notes.#each')
Simple.

Filling Ember selection with data received from server

I would like to receive json data from server and then generate html selection tag in Ember. This is my handlebars template:
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="rankings">
{{view Ember.Select contentBinding="countries" optionLabelPath="countries.name" optionValuePath="countries.path"}}
</script>
and my Ember trunk
App.ApplicationAdapter = DS.RESTAdapter;
App.Router.map(function() {
this.route('rankings')
});
App.RankingsRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('countries', this.store.findAll('country'));
}
});
App.RankingsController = Ember.Controller.extend({
countries: []
});
App.Country = DS.Model.extend({
path: DS.attr('string'),
name: DS.attr('string'),
}
It is not working fine. I am not having any errors in console and template is not rendering with this route and controller. What can be wrong?
Ember.Select looks for data on your controller's model. You have the countries array set up outside of your content, so it will not be able to view the data.
Personally, I would do it in the following way, though there are a couple of different approaches you can take to get similar results:
App.ApplicationAdapter = DS.RESTAdapter;
App.Router.map(function() {
this.route('rankings')
});
App.RankingsRoute = Ember.Route.extend({
model: function() {
return {countries : this.store.findAll('country')};
}
});
App.RankingsController = Ember.Controller.extend({
});
App.Country = DS.Model.extend({
path: DS.attr('string'),
name: DS.attr('string'),
}

Getting data from DS.PromiseArray in EmberJS

I'm new to emberJS and I'm having some trouble working with promises.
Here is my router:
this.resource('menus', function(){
this.resource('menu', {path: '/:menu_id'}, function(){
this.resource('submodule', {path: '/:submodule_id'});
});
});
});
I have nested routes, and the child route returns a menuss object based on a given id.
Here is my MenuRoute:
App.MenuRoute = Ember.Route.extend({
model: function(params){
return this.store.find('menuss', params.menu_id);
}
});
Here are my models:
App.Menuss = DS.Model.extend({
name: DS.attr('string'),
subModule: DS.hasMany('submodule', {async:true})
});
App.Submodule = DS.Model.extend({
name: DS.attr('string'),
content: DS.attr('string')
});
The 'subModule' attribute of Menuss model contains an array of Submodule model id's.
Inside my menu template, I'm receiving a menuss object and I want to display the SubModules each menu item has.
However, when I call {{this.subModule}}, it returns <DS.PromiseArray:ember488>. How can I get the contents from this subModule array?
I looked at some similar questions where they say use the then() method, but I can't seem to figure it out here.
In the template you'll want to iterate the property since it's an array, ember/handlebars will deal with the synchronicity of the PromiseArray.
{{#each item in subModule}}
{{item.name}}
{{/each}}

Ember.js Router v2 dynamic slug

In the following example, using the new Router v2 API, the ember application behaves as expected with one exception. When hovering over the dynamically created links, using a registered #linkTo Handlebars the url shows undefined.
How do I have a slug field in the URL?
Here is the model
App.Todo = DS.Model.extend({
slug: DS.attr('string'),
date: DS.attr('date'),
updated: DS.attr('date'),
task: DS.attr('string'),
description: DS.attr('string')
});
My Router
App.Router.map(function(match){
this.route('index', {path: '/'});
this.resource('todos', {path: '/todos'}, function(){
this.resource('create', {path: '/create'});
this.resource('todo', {path: '/:slug'}, function(){
this.resource('edit', {path: 'edit'});
});
});
});
I know that this does show 'undefined', but this would be a nice (Handlebars)
{{#each todo in tasks}}
<div class="user">
{{#linkTo todo todo.slug}}<h4><i class="icon-list"></i>{{todo.task}}</h4>{{/linkTo}}
<p>{{todo.description}}</p>
</div>
{{/each}}
Thanks for any pointers! I'm using Ember-data also
Here is a example fiddle
http://jsfiddle.net/R2SPs/6/
This works for ember routing v2.1 (01.16.13)
Thanks to rakl on #emberjs on IRC here is a mixin that solves the problem
App.SlugRouter = Ember.Mixin.create({
serialize: function(model, params) {
var name, object;
object = {};
name = params[0];
object[name] = model.get('slug');
return object;
}
});
Now just place that in your Router and your golden
App.TodoRoute = Ember.Route.extend(App.SlugRouter,{
//insert your code
});
The path of the route is "todo.index" with the resource definition:
this.resource('todo', {path: '/:slug'}, ...
So create Route and Controller for it.