Ember syntax errors - ember.js

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({

Related

How can I avoid "Assertion Failed: `id` passed to `findRecord()` has to be non-empty string or number" when refreshing an ember page?

There's this really annoying feature about Ember that I'm not sure how to get around. I may have a url that looks like the following
http://{my-blog-name}/posts/view/{some-blogpost-ID}
The way I get to this page is by clicking on a link inside of my {my-blog-name}/posts page. This works and will display the page as expected. However, if I try to refresh the page, or if I just literally type my http://{my-blog-name}/posts/view/{some-blogpost-ID} into my url search box, I will get
Assertion Failed: `id` passed to `findRecord()` has to be non-empty string or number
Here is how I navigate to the posts/view/{some-blog-id} page.
post.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.findAll('post');
}
});
posts.hbs
<li class="title-list-item">{{#link-to "posts.view" posts}}{{posts.title}}{{/link-to}}</li>
view.js
import Ember from 'ember';
var siteId;
export default Ember.Route.extend({
model(params) {
siteId = params.site_id;
return this.store.findRecord('post', params.site_id);
}
});
view.hbs
<div id="Links">
<h1 id="blog-header-title">My Blog</h1>
<!--<p>{{!#link-to 'welcome'}} See about me{{!/link-to}}</p>-->
{{outlet}}
</div>
{{outlet}}
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('index', { path: '/' }); // This is usually automatic if path undeclared, but declared here to support /index below
this.route('posts', function() {
this.route('view', {path: '/view/:post_id'});
});
this.route('welcome');
}
This is really frustrating because it means I can't make a blog post and share the link with a friend. Why does this happen and is there a good way to get around it?
posts.js route is returning all the posts available, that's the RecordArray.
<li class="title-list-item">{{#link-to "posts.view" posts}}{{posts.title}}{{/link-to}}</li>
so in the above posts - refers to single post model or RecordArray of post model ?. if the above is single model then you will receive params.post_id in model hook of view.js, currently you are taking params.site_id instead of params.post_id.
Reason for not executing the model hook.
https://guides.emberjs.com/v2.13.0/routing/specifying-a-routes-model/#toc_dynamic-models
Note: A route with a dynamic segment will always have its model hook
called when it is entered via the URL. If the route is entered through
a transition (e.g. when using the link-to Handlebars helper), and a
model context is provided (second argument to link-to), then the hook
is not executed. If an identifier (such as an id or slug) is provided
instead then the model hook will be executed.

Overriding LinkComponent EmberJs 1.13.15

Im Using EmberJs 1.13.15 and Ember-CLI , i was trying to slightly modify the main LinkComponent behavior by adding the following code:
app/components/nav-link-to.js:
import Ember from 'ember';
export default Ember.LinkComponent.extend({
tagName: 'li'
});
app/templates/components/nav-link-to.hbs:
{{yield}}
and im using this component in:
app/templates/nav-bar.hbs:
<ul class="nav navbar-nav">
{{#nav-link-to 'index'}}Home{{/nav-link-to}}
</ul>
but whenever i open the nav-bar template in the browser nothing shows up
and in ember inspector's console it shows the following error
Uncaught TypeError: Cannot read property 'slice' of undefined
Any help?
Thanks in advance.
You will have to add the params in your component. Also you will have to call this._super in init method of component. Below is the working component code for extended link-to.
import Ember from 'ember';
export default Ember.LinkComponent.extend({
tagName: 'li',
positionalParams: 'params',
init: function() {
this._super(...arguments);
},
didReceiveAttrs: function() {
this.attrs.params = this.get('params');
this.attrs.hasBlock = true;
}
});

Ember nested route show.hbs params not working

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.

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

Does the application route load automatically and load the application.hbs in an Ember app?

I have this as my router.js. Note that it has no application route:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('todos', { path: '/'});
});
export default Router;
When I hit the home path, I see my application.hbs template and the todos.hbs template is loaded in the outlet. This is my application.hbs:
<section id="todoapp">
<header id="header">
<h1>todos header in application.hbs</h1>
</header>
{{outlet}}
</section>
<footer id="info">
<p>
Footer in application.hbs. Double-click to edit a todo
</p>
</footer>
Why does my application.hbs get loaded?
I assume Ember knows to also load the todos.js in my routes folder which is this:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
let todos = [
{
title: 'Learn Ember',
complete: false,
},
{
title: 'Solve World Hunger',
complete: false,
}
];
return todos;
}
});
And this is my todos.hbs template:
<h2>Todos Template</h2>
<ul>
{{#each model as |todo|}}
<li>
{{todo.title}}
</li>
{{/each}}
</ul>
Main questions
1. Why does my application.hbs get loaded when I hit the home route?
2. What is export default mean?
3. What is the line import Ember from 'ember' doing? Where is 'ember' coming from?
The application route is loaded in every Ember.js application. See http://guides.emberjs.com/v2.1.0/routing/defining-your-routes/#toc_the-application-route
export default is part of the ES6 module specification. See http://exploringjs.com/es6/ch_modules.html It takes the object or variable to be returned as the default thing to be imported when that module is imported inside another module.
The 'ember' namespace is built into Ember CLI. Its default export is itself, the Ember variable, which was once a global variable in prior versions of Ember.