Sub route appending empty record to collection I've got a bit of a tricky problem and I'm hoping you peeps can help.
This works as expected BUT if I refresh the page with a location sub route the locations list gets an empty record appended to the end.
App.Router.map ->
this.resource 'home', { path: '/' }
this.resource 'locations', ->
this.resource 'location', { path: ':slug' }
this.resource 'services'
this.resource 'contact'
this.resource 'login'
App.LocationsRoute = Ember.Route.extend
model: ->
this.store.find 'location'
App.LocationRoute = Ember.Route.extend
serialize: (model, params)->
slug: model.get 'slug'
model: (params)->
this.store.find 'location', params.slug
Any help greatly appreciated
Related
I've scouring for a bit, but can't find an answer to this. I've got an Ember route on a Rails app, and I would like one of the model records to be displayed by default when visiting the URL (right now, a user needs to click on a specific link to retrieve the data).
For example, when visiting /albums, I would like /albums/38 to be active and visible without forcing a redirect. Is that possible?
Thanks
App.Router.map ->
#resource 'albums', path: '/', ->
#resource 'album', path: '/:id'
App.AlbumsRoute = Ember.Route.extend
model: -> #store.find 'album'
Add an 'index' route for the 'albums' resource and redirect to the 'album' route with the first model. The index route will only be hit when you hit just the albums resource, and not when you hit deeper (aka not when you hit /albums/1).
App.AlbumsRoute = Ember.Route.extend
model: -> #store.find 'album'
App.AlbumsIndexRoute = Ember.Route.extend
model: ->
album = this.modelFor('albums').get 'firstObject' # This can be whatever...
this.transitionTo('album', album) if Ember.isEmpty(album) is no
I have 2 models Post and Comment. Both have own routes: PostRoute and PostCommentsRoute, in the first case I simply use #store.find to load model data but I have a problem with the second route. When I try to refer to Post and then get its comments, they loads but don't update when I add new one. If I use #store.find 'comment', it stays updated however loads everything, so it's not the point. How to get only comments related to the post and keep them updated?
App.Post = DS.Model.extend
comments: DS.hasMany 'comment', async: true
App.Comment = DS.Model.extend
post: DS.belongsTo 'post'
text: DS.attr 'string'
App.Router.map ()->
#resource 'post', path: '/post/:post_id', ()->
#route 'comments'
App.PostCommentsController = Em.ArrayController.extend
newComment: ""
needs: 'post'
post: Em.computed.alias 'controllers.post'
sortProperties: ['created'],
sortAscending: false
actions:
addComment: ()->
commentText = #get 'newComment'
post = #get 'post'
comment = #store.createRecord 'comment',
text: commentText
post: post.get 'content'
#set 'newComment', ''
comment.save()
App.PostRoute = Em.Route.extend
model: (params)->
#store.find 'post', params.post_id
App.PostCommentsRoute = Em.Route.extend
model: (params)->
# loads only comments to parent post but doesn't update
post = #modelFor 'post'
post.get 'comments' # /api/posts/1/comments
App.PostCommentsRoute = Em.Route.extend
model: (params)->
# updates but loads all comments
#store.find 'comment' # /api/comments
After you save your comment you have to push it on the post's comments:
comment.save().then(function () {
post.get('comments').push(comment);
// or if that doesn't work you may need to resolve the promise:
post.get('comments').then(function (comments) {
comments.push(comment);
});
});
The Ember.js application
# routes/application.js.coffee
########################################
App.ApplicationRoute = Ember.Route.extend
model: ->
#store.findAll('category').then (records) ->
{
categories: records
}
# routes/categories.js.coffee
########################################
App.CategoriesRoute = Ember.Route.extend
model: ->
#store.find 'category'
# routes/category.js.coffee
########################################
App.CategoryRoute = Ember.Route.extend
model: (params) ->
serialize: (model, params) ->
id: model.get('slug')
# templates/application.hbs
########################################
{{ partial 'categories' }}
<p>---</p>
{{ outlet }}
# templates/categories.hbs
########################################
<h1>Categories...</h1>
{{#each category in categories}}
{{#link-to 'category' category}}
{{category.title}}
{{/link-to}}
{{/each}}
# templates/category.hbs
########################################
<h2>{{title}}</h2>
<h3>{{description}}</h3>
# router.js.coffee
########################################
App.Router.map ->
#resource 'categories', path: 'categories'
#resource 'category', path: 'category/:slug'
# store.js.coffee
########################################
App.ApplicationAdapter = DS.ActiveModelAdapter.extend
namespace: 'api/v1'
What I am trying to accomplish
I am loading Category on the Application route so the data can be used to render the site-wide navigation via the categories partial.
Model is acquired successfully and stored, according to the Ember console. If it makes any difference, one-to-many data is being sideloaded, called Sections, which is also stored successfully.
The category partial is rendered as expected, with links to each section. Clicking on them yields the rendering of the title and description.
What is wrong
Refreshing the application on the route of say, /#/category/title-1, doesn't render the category view (both title and description). However, clicking on the links generated in the categories partial will render the view.
What I expect on page load is the rendering of the category view, without the need of clicking on the categories links. What am I doing wrong?
After playing around with the Application for too long, I figured out a solution to my problem.
When using the Ember console, I saw that the model for the Category view was referenced to [Object object] and not App.Category. I had to specify the store to search by the slug. Therefore, the code looks like this
# routes/category.js.coffee
########################################
App.CategoryRoute = Ember.Route.extend
model: (params) ->
serialize: (model, params) ->
id: model.get('slug')
#store.find('category', params.slug)
The view is now rendered on page load.
I want to use the information already received within a linked template. Nesting routes has created a whole heap of errors, and I'm a little lost on how to pass this data, but it seems like it must be possible?
This works, but strikes me as a poor hack. Ideally I'd only want one API round-trip...
App.Router.map ->
#resource 'photos'
#route 'photo', path: 'photo/:photo_id'
App.PhotosRoute = Ember.Route.extend
model: ->
Ember.$.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?tags=cake&tagmode=all&format=json&jsoncallback=?')
setupController: (controller,model) ->
controller.set 'photos', model.items.map (i) ->
i.id = model.items.indexOf(i)
App.PhotoRoute = Ember.Route.extend
model: (params) ->
jQuery.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?tags=cake&tagmode=all&format=json&jsoncallback=?').then (api) ->
api.items[params.photo_id]
App.PhotosController = Ember.ObjectController.extend
itemController: 'photo'
{{#linkTo 'photo' this }}<img {{bindAttr src="media.m"}} />{{/linkTo}}
You can use the modelFor(routeName) to get the model from some route. In your case probally you will fetch all data in PhotosRoute, and want to reuse it. You can use this in your PhotoRoute:
App.PhotoRoute = Ember.Route.extend
model: (params) ->
#modelFor('photos').items[params.photo_id]
So just one api call will be done.
Ember shows me the following error: Uncaught Error: No route matched the URL '/users'
Sks.IndexRoute = Ember.Route.extend
redirect: ->
this.transitionTo 'users'
Sks.Router.map ->
this.resource 'users', path: 'users/:user_id'
Sks.UsersRoute = Ember.Route.extend
setupController: (controller, model) ->
this.controllerFor('users').set 'content', Sks.User.find()
this.controllerFor('currentUser').set 'content', Sks.CurrentUser.find 1
this.controllerFor('top').set 'content', Sks.Top.find()
this.controllerFor('hamsters').set 'content', Sks.Hamster.find()
Everything works when I remove the dynamic segment.
Version: v1.0.0-rc.1-78-gd4e6a5c
edit#1
added IndexRoute
In Ember, collections and items actually use separate routes. Here's how I do it:
App.Router.map(function () {
this.resource('contacts', { path: '/contacts' });
this.resource('contact', { path: '/contact/:contact_id' });
});
App.IndexRoute = Ember.Route.extend({
redirect: function () {
this.replaceWith('contacts');
}
});
App.ContactsRoute = Ember.Route.extend({
model: function (params) {
return App.Contact.find();
}
});
App.ContactRoute = Ember.Route.extend({
model: function (params) {
return App.Contact.find(params.contact_id);
}
});
Here's a working jsFiddle.
It seems that I should have RTM :)
Sks.Router.map ->
this.resource 'users', ->
this.resource 'user', path: ':user_id'