I'm trying to wrap my head around dynamic segments and I want to be able to use a slug or other property instead of the id. When I can get things working it feels like a fluke. (I'm using ember 2.7+)
I plan on using ember-data, but I want to ensure I'm in control - and so I don't want to use the :post_slug / underscore style that has some built in magic that I want to avoid.
Here is an ember-twiddle Here are step-by-step commits in a github repo
My thought process
1. Conceptually, lets say I need a list of cats - so I need to describe the model for what a 'cat' is.
models/cat.js
import Model from "ember-data/model";
import attr from "ember-data/attr";
export default Model.extend({
name: attr('string'),
slug: attr('string')
});
2. define where the dynamic segment will be in the url. I'm going to use catId to prove a point instead of cat_id or :id like most of the tutorials I've seen. For this example, I'm also writing an actual app structure instead of the smallest router possible - to test the edges of this.
router.js
Router.map(function() {
this.route('index', { path: '/' });
this.route('cats', { path: '/cats' }, function() {
this.route('index', { path: '/' }); // list of cats
this.route('cat', { path: '/:catId' }); // cat spotlight
});
});
3. pull in the catData into the store ~ in the /cats route
routes/cats.js
import Ember from 'ember';
const catData = [
{
id: 1,
name: 'Dolly',
slug: 'dolly'
},
{
id: 2,
name: 'kitty cat',
slug: 'kitty-cat'
},
{
id: 3,
name: 'Cleopatra',
slug: 'cleo'
}
];
export default Ember.Route.extend({
model() {
return catData;
// return this.get('store').findAll('cat'); // with mirage or live api
}
});
4. create the templates... + set up the 'cat' route. The records are in the store... right? so I should be able to 'peek' at them based on id. The docs use params
- but - "Ember will extract the value of the dynamic segment from the URL for you and pass them as a hash to the model hook as the first argument:" ~ and so the params can really be anything you want... and is just replaced with the dynamic segment - so to that point / I'm using 'passedInThing' just to assert control over the confusing conventions (many tutorials use param instead of params)
routes/cats/cat.js
model( passedInThing ) {
return this.store.peekRecord('cat', passedInThing.catId );
}
5. At this point, I should be able to navigate to the url /cats/2 - and the 2
should get passed through the model hook - to the query. "Go get a 'cat' with an id of 2" --- right??? ((the twiddle example uses a hard-coded set of catData - but in my other attempts I'm using mirage: http://ift.tt/29eTvpR
6. Typing in the segment works - but for link-to
helpers I need to pass in the explicit cat.id
<span></span>
7. I can get all that working - but I don't want an ID in the URL. I want cats/cleo
with the 'slug' ~ in theory I can just switch catId
for catSlug
and cat.id
to cat.slug
etc - but that is not the case. I've seen many tutorials outlining this but they are outdated. I've tried passing in { slug: params.slug }
and every combo of find query and peek etc. Sometimes the url will work but the model wont render - or the opposite.
8. This seems like 101 stuff. Can anyone explain this to me? Oh wise emberinos - come to my aid!