Ember nested route show.hbs params not working - ember.js

I am trying to show a 'show' template for a list of items.
My index.hbs works as follows:
route/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('item');
}
});
template/items/index.hbs
items/index.hbs
<ul>
{{#each model as |item|}}
<li>
{{#link-to 'items.show' item}}
{{item.name}}
{{/link-to}}
</li>
{{else}}
<li>No contacts found.</li>
{{/each}}
</ul>
However, when I click a link that is generated, it brings me to the correct route (localhost:4200/items/1), however, it gives me the following error: Error while processing route: items.show Assertion Failed: You may not pass 'undefined' as id to the store's find method Error: Assertion Failed: You may not pass 'undefined' as id to the store's find method
Here is my show.js and hbs:
routes/show.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.findAll('item', params.id);
}
});
and templates/items/show.hbs
{{name}}
here is router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
export default Router.map(function() {
this.resource('items', function() {
this.route('show', {path: ':item_id'});
});
});
I can not figure out when its not working! I read that params is not sent from index to show..but then?!
Thank you in advance. Any exaggerated answer would be most appreciated.

Hope this helps. http://ember-twiddle.com/147af82f6fa69bf97414
After looking at your code snippets closely, I realized that inside your item:model hook you are passing params.id to store.findAll return this.store.findAll('item', params.id), however in your router.js you specified it as item_id. You should be using the same param name used in your route definition.

Related

Ember syntax errors

I am learning ember.js with a tutorial that is built in to their documentation. Having installed it successfully, I followed the steps and created a new application with ember new ember-quickstart, generated a template and defined a route. However, the data that I've included in the route model is not being rendered (there appears to be a parsing error due to an unexpected token default), but I have no idea what it might be referring to. I have pasted the code exactly as it appears. Any suggestions as to what might be causing the error?
SyntaxError: ember-quickstart/routes/scientists.js: Unexpected token (3:2)
routes/scientists.js
import Ember from 'ember';
default Ember.Route.extend({
model(){
return['Marie Curie', 'Albert Einstein', 'Andrei Sakharov']
}
});
templates/scientists.hbs
<h2>List of Scientists</h2>
<ul>
{{#each model as |scientist|}}
<li>{{scientist}}</li>
{{/each}}
</ul>
templates/application.hbs
<h2 id="title">Welcome To Ember</h2>
{{outlet}}
app/router.js
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('scientists');
});
export default Router;
default Ember.Route.extend({
should be:
export default Ember.Route.extend({

How can I get the Id from the URL in an Ember Route?

I have a two panel display where I show a list of items on the left, then detail about a selected item on the right (using nested route).
My route looks like this:
Router.map(function() {
this.route('authenticated', {path: '/'}, function() {
this.route('bakery', function() {
this.route('cakes', function() {
this.route('detail', { path: '/:id' });
});
});
});
});
My URL looks like
http://localhost:3333/bakery/cakes/e34b3ce3
When an item is selected, it is set to "active" (temporary property on the model - default is false) and highlighted via an action on the bakery/cakes route. The detail is then shown on the right.
If I refresh the page, the item is no longer highlighted - but the detail is still shown.
Ideally I'd like to use the afterModel() hook in the bakery/cakes route to set that item back to active again, but I've been unable to get the Id to be able to do this.
I've tried the following:
Accepted answer from here
This question doesn't help me as the model will have reloaded and my "active" property will be false so I can't just select where active = true.
I'm using ember 2.5.0. Thanks.
I wonder if it'd be better to architect your structure a bit differently (from what I assume you're doing).
First, load all of the cakes on the authenticated.bakery.cakes route;
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('cakes');
}
});
Secondly, show your "full width" cakes list on the authenticated.bakery.cakes.index template (the cake models will be inherited);
<div class="full width cake list">
{{#each model as |cake|}}
{{#link-to "authenticated.bakery.cakes.detail" cake.id}}
{{!-- cake photo --}}
{{cake.name}}
{{!-- other cake details... --}}
{{/link-to}}
{{/each}}
</div>
Next, on your authenticated.bakery.cakes.detail route, load the specific cake along with the list of cakes;
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
let cakes= this.modelFor('authenticated.bakery.cakes');
return Ember.RSVP.hash({
cakes: cakes,
cake: cakes.findBy('id', params.id)
});
}
});
Finally on the authenticated.bakery.cakes.detail template, show the condensed/narrow list of cakes along with the specific cake details. And using {{link-to}}, the 'active' class will automatically be applied;
<div class="narrow width cake list">
{{#each model.cakes as |cake|}}
{{#link-to "authenticated.bakery.cakes.detail" cake.id}}
{{cake.name}}
{{/link-to}}
{{/each}}
</div>
<div class="cake details">
{{model.cake.name}}
</div>
As another option, change your model active flag on the proper route hooks should work. (I think anyway, haven't done this myself.) On your authenticated.bakery.cakes.detail route;
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('cakes', params.id);
},
afterModel(cake) {
cake.set('active', true);
},
actions: {
willTransition() {
this.get('controller.model').set('active', false);
}
}
});

Im trying to understand ember and ember cli conventions and file structure

I have set up a simple api and a new ember app using ember cli
However, while I can get a full list of 'items' to appear, I can't get a single item to work using params.
I have my files set up like the following:
/models
item.js
/routes
/items
index.js
show.js
/templates
/items
index.hbs
show.hbs
application.hbs
index.hbs
items.hbs
router.js
For reference, here is what I have in the files
I set up my models/item.js a follows:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string')
});
I added my code to my router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('items', function() {
this.route('show', { path: '/:item_id' });
});
});
export default Router;
Then I created my templates/index.hbs
{{outlet}}
And finally, added my templates/items/index.hbs
<ul>
{{#each model as |item|}}
<li>
{{#link-to 'items.show' item}}
{{item.name}}
{{/link-to}}
</li>
{{/each}}
</ul>
This works as intended.
However, when I click a link (/items/1), it no longer performs as expected. It will show the items/show.hbs correctly assuming I do no use any handlebars variables ({{item.name}}). For example, If I just include text, this is my items/show.hbs it will display the text. When I add in, {{name}} it displays a blank page
Here is my templates/items/show.hbs
{{name}}
and my routes/items/show.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.queryRecord('item', params.item_id);
}
});
What am I doing wrong?
Thanks in advance!
It looks like you're not using reference to model when using it in template
Here is my templates/items/show.hbs
{{name}} < This is a model's property- name
Correct usage: {{model.name}}
and my routes/items/show.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.queryRecord('item', params.item_id);
}
});
Way of using hash
return Ember.RSVP.hash({
something: store.find('y', { study: params.study_id }),
somethingElse: store.find('x', 1),
});

Unable to use value from an Ember Data store in template

I'm building a simple application using Ember v1.8.1, Ember CLI 0.1.15 and Ember Data 1.0.0-beta.15 in an attempt to learn the basics of Ember.js. Data is coming from a simple REST API, so I'm using the DS.RESTAdapter and DS.RESTSerializer. The payload is normalized in the serializer, because the API doesn't properly wrap its data in the required hashes.
I'm trying to implement an edit route, but am unable to populate the form fields of that template or even display a simple value. My index route, displaying a list of posts, works as expected, but edit doesn't for some reason.
Using {{title}} in my template doesn't render the value, but outputs a string of unexpected data, something along the lines of: <my-app#model:post::ember413:21>. I'm probably passing something improperly from the route or elsewhere, but I don't know what and where exactly.
Below is some of my relevant code:
app/router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('login');
this.resource('posts', function() {
this.route('add');
this.route('view', { path: ':post_id'});
this.route('edit', { path: ':post_id/edit'});
});
});
export default Router;
app/routes/posts/edit.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function(params){
return this.store.find('post', params.post_id);
}
});
app/routes/posts/index.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function(){
return this.store.find('post');
}
});
app/controllers/posts/edit.js
import Ember from 'ember';
export default Ember.ObjectController.extend();
app/serializers/application.js
import Ember from "ember";
import DS from "ember-data";
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
primaryKey: 'ID',
attrs: {
author: { embedded: 'always' }
},
extractSingle: function(store, type, payload, id) {
payload = { post : payload };
return this._super(store, type, payload, id);
},
extractArray: function(store, type, payload) {
payload = { posts : payload };
return this._super(store, type, payload);
},
serializeIntoHash: function(hash, type, record, options) {
Ember.merge(hash, this.serialize(record, options));
}
});
app/templates/edit.hbs
<div class="page">
<div class="page-content">
<h2>{{title}}</h2>
{{{content}}}
</div>
</div>
app/templates/index.hbs
<div class="page">
<div class="page-content">
<ul>
{{#each}}
<li>
<h2>{{title}}</h2>
{{{content}}}
</li>
{{/each}}
</ul>
</div>
</div>
Having looked at some examples the above should work, so probably there's an error in the serializer. In the route I can access values from the store however. The following logs the expected data when used in the model method of my edit.js route:
this.store.find('post', params.post_id).then(function(post) {
console.log(post.get('title'));
});
UPDATE: Here is a JS Bin recreating most of the application without Ember CLI. The behaviour is exactly the same as on my local machine; the edit route doesn't properly show the content value (title works, for some reason). When I swap to fixtures instead of the API output the problem remains the same. Also the model in the bin doesn't map to all the values returned by the API, but that doesn't seem to make a difference.
UPDATE 2: Seems the content entry of the returned payload is causing the problems, when I rename the key it's displayed correctly in the edit template. Didn't realise this before, because I was so focussed on getting the content value to display and forgot to test other values. Not sure why it happens only happens on a nested route though and with that particular keyword.
UPDATE 3: If I understand correctly, this might be related to an outstanding issue for Ember Data, there's a proposal for reporting such collisions as well.

ember.js - ember-cli: ember-data not available on child view

I'm using the latest ember-cli and currently testing it, creating very simple app using ember-data and http-mock for RESTAdapter - ember generate http-mock api-server
Single post get from the API:
http://localhost:4200/api/api-server/posts/1
Result
{"post":
{
"id":1,
"title":"How to write a JavaScript Framework",
"author":"Tomhuda Katzdale",
"body":"Lorem ipsum dolor sit amet"
}
}
Here are all the relevant codes:
Adapters
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
namespace: 'api/api-server'
});
Model
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
author: DS.attr('string'),
body: DS.attr('string')
});
router.js
import Ember from 'ember';
var Router = Ember.Router.extend({
location: EmbercliDataENV.locationType
});
Router.map(function() {
this.route('application');
this.resource('posts', function() {
this.resource('post', { path: ':post_id' });
});
});
export default Router;
Routes (posts and post) - view and child view
posts route
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('post');
}
});
post route
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.find('post', params.post_id);
}
});
template
posts.hbs
<h2>Posts List</h2>
<ul>
{{#each}}
<li>
{{#link-to 'post' this}}{{title}}{{/link-to}} | {{author}} | {{body}}
</li>
{{/each}}
</ul>
{{outlet}}
post hbs
<h2>Single Post</h2>
<p>Post title: {{title}}</p>
<p>Post author: {{author}}</p>
<p>Post body: {{body}}</p>
THE PROBLEM: if you look at the screen-cap below, in the chrome ember debugger, the single post model is hooked to the post route but is not printed in the post.hbs
Using just the ember starter kit, I got no problem at all with the exact same app.
Thank you for any help, cheers
UPDATE
The following is the exact same Ember app coded using the starter kit, host in xampp and using PHP Slim framework for REST Api. Working FINE!
try to fix your data, because post is nested in posts, try this:
{"post":[
{
"id":1,
"title":"How to write a JavaScript Framework",
"author":"Tomhuda Katzdale",
"body":"Lorem ipsum dolor sit amet"
}]
}
check within your posts hbs if the data is visible, then post should work fine
After browsing the Ember.js forum I got the answer there - http://discuss.emberjs.com/t/strange-behavior-w-retrieving-model-from-controller/6155
It seems when using the Ember generate controller command, you end up with Ember.Controller, not Ember.ObjectController or Ember.ArrayController lol.
I edit my post controller from: (generate by the Ember generate controller command)
export default Ember.Controller.extend({
});
to
export default Ember.ObjectController.extend({
});
and now the model is binding :D
<h2>Posts List</h2>
<ul>
{{#each}}
<li>
{{#link-to 'post' post}}{{title}}{{/link-to}} | {{author}} | {{body}}
</li>
{{/each}}
</ul>
{{outlet}}
1.instead of 'this' use post, hope this will fix the issue
http://emberjs.com/guides/templates/links/#toc_adding-additional-attributes-on-a-link