Nested route in resource not being accesible by Link-To - ember.js

I can't make it work. The problem lies in the projects route, notes and info routes are not being linked
App.Router.map(function() {
this.resource('about');
this.resource('projects', function() {
this.route('new');
this.resource('project', { path: ':project_id'}, function(){
this.route('info', { path: "/info"});
this.route('notes', { path: "/notes"});
});
});
this.resource('posts', function() {
this.route('new');
this.resource('post', { path: ':post_id' });
});
});
The project template making the call to project_notes.hbs and project_info.hbs is as follows.
<div class="navbar navbar-inverse">
<div class="navbar-inner">
<a class="brand" href="#">{{title}}</a>
<ul class="nav">
<li>{{#link-to 'project.Info' project}}Info{{/link-to}}</li>
<li>{{#link-to 'project.Notes' project}}Notes{{/link-to}}</li>
</ul>
</div>
</div>
{{outlet}}
After reading this I was able to go a step further but still it's not working. Let me know if you need more info like the project model or anything.
Error
This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.
Thanks in advance.
EDIT
The route is ProjectInfoRoute which is fine, the pointing URL is /projects/:project_id/info which is also absolutely fine. But when I click in the Project in order to go to Project/Project_id now it says There is no route named info.index
This is defining info as a this.route if I use this.resource it's like the route for info gets twisted since it's InfoRoute instead of ProjectInfoRoute. (If I go for the resource, after getting into the project template, I click on info and I can't get to see that template.) I'm scratching my head here.

Don't send it, additionally it should be link-to should be lower case
<ul class="nav">
{{#if model}}
<li>{{#link-to 'project.info' model}}Info{{/link-to}}</li>
<li>{{#link-to 'project.notes' model}}Notes{{/link-to}}</li>
{{else}}
do some other menu here, go to projects, or something
{{/if}}
</ul>
additionally you can find out the scope and values of properties really easy by tossing them into the template or logging them
{{project}}
{{log project}}
{{log model}}
{{log this}}

Related

Can't get link-to to bring me to a route

I've been trying to get this button to take me to a route called 'manage'. But somehow the data I'm passing with the {{#link-to}} does not seem to work.
router.js
this.route('manage', {path: '/:stack_id/manage'});
main.hbs
<div class="row">
<div class="pull-right">
{{#link-to "manage" list}}
<button class="btn-gray"> Manage People {{fa-icon "coffee"}}</button>
{{/link-to}}
</div>
</div>
main.js where {path: '/:stack_id'}
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.find('list', params.stack_id);
},
I've tried replacing {{#link-to "manage" list}} with list.id and model.id, both of these brings the message that
"This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.
You need to pass model.id to link-to helper but model can't be null. Make sure param is defined when you call store.find method and API returns correct response/record is found. You can use {{log model}} to check if model is defined in your template.

emberjs : add active css class to link based on current route

I am using Ember version 1.8 . Does anyone know how to automatically highlight menu link when user is in that route. Plese help. I saw few Stack overflow posts on doing it. but they looks old and is not working for me
I have the following menu in handlebars template
<ul class="nav navbar-nav">
<li>
{{#link-to 'posts'}}Posts{{/link-to}}
</li>
<li>
{{#link-to 'comments'}}Comments{{/link-to}}
</li>
</ul>
router.js looks like
this.resource('post', { path: 'posts/:post_id'},function(){
this.resource('comments', { path: '/comments' });
});
Ember automatically adds a class of active to a routed currently being visited. You can define what that should look like in css, for example:
.active {
background: yellow;
}
The rest just works...
See a working demo here

How to link to each nested routes in ember?

I've got an ember app where my routing looks like this:
App.Router.map(function() {
this.resource('works', {path: '/works'}, function(){
this.route('work', {path:':work_id'})
});
});
I want to be able to link each of my work in my index template, for my naviguation. I tried this but it didn't work:
<script type="text/x-handlebars" data-template-name='application'>
<header id="header">
<nav id="main-nav" role="navigation">
<div class="item-container">
{{#link-to 'works' tagName='div' classNames="navItem work" }}
<p>Works</p>
{{/link-to}}
<ul>
{{#link-to 'work' works work}}{{work.title}}{{/link-to}}
</ul>
</div>
</nav>
</header>
<main id="main">
{{outlet}}
</main>
</script>
If you need more info just let me know.
Your index route definitions should look like this (assuming you are using Ember Data):
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('work');
}
});
Then in your index template go through {{each}} of the App.Work records and link to the works.work route:
<ul>
{{#each}}
<li>{{#link-to 'works.work' this}}{{title}}{{/link-to}}</li>
{{/each}}
</ul>
When linking to a route, you do resource.route
{{#link-to 'works.work' work}}{{work.title}}{{/link-to}}
In this case I'm assuming work is a property that is a model, if not, you'll need to show your router.

Blank entries added to Ember Data

I'm currently learning EmberJS as I feel single page apps using a JS framework and consuming a backend API are the way things are going to be moving. I've recently learned Laravel without any particular problem, but I'm finding Ember remarkably difficult.
Most of my issues I've worked through, but I'm having one that I don't even know how to debug.
Essentially, my interface displays a list of clients. Clicking on a name goes to that client. All of this is connected to a PHP/Laravel based API, which is working entirely fine and in the right format. Data is not the problem here.
That said, I should point out that my data does not have an "id" strictly, but connects using something more like a guid: 912ec803b2 instead of 231. The API is built to handle that, and it's a requirement. It also means there is no "id" in the data, but there is a "hash" which may potentially be confusing ember in some way?
This basic functionality just doesn't seem to work correctly. When a user clicks the Client link, it does navigate to the client. But it's adding a blank row to the clients list page, then going to the client page. Returning to the clients page shows the extra blank row, and the same thing will recur if clicked again.
Checking the Ember inspector in Chrome shows the data collection increasing, with blank data being added. I'm not sure why.
I've posted the code here. This should be all that's necessary. Is this behaviour a common trap for young players, of have I done something unusual?
Apologies for the length, just didn't want to omit something relevant.
// app.js
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function() {
this.resource('clients', function() {
this.route('new');
});
this.resource('client', { path: 'clients/:client_hash' }, function(){
});
});
App.Store = DS.Store.extend({
url: 'http://myclientinfo'
});
App.ApplicationAdapter = DS.RESTAdapter.extend({
namespace: 'api'
});
App.Client = DS.Model.extend({
name: DS.attr('string'),
hash: DS.attr('string')
});
App.ClientsRoute = Ember.Route.extend({
model: function(){
return this.store.find('client');
}
});
App.ClientIndexRoute = Ember.Route.extend({
model: function(params){
return this.store.find('client', params.client_hash);
}
});
// templates
<script type="text/x-handlebars">
<div class="container">
<ul class="nav nav-pills">
<li>{{#link-to 'clients'}}Clients{{/link-to}}</li>
</ul>
{{outlet }}
</div>
</script>
<script type="text/x-handlebars" id="client">
client outer
{{outlet}}
</script>
<script type="text/x-handlebars" id="clients">
client outer
{{outlet}}
</script>
<script type="text/x-handlebars" id="client/index">
client index
<h1>{{name}}</h1>
</script>
<script type="text/x-handlebars" id="clients/index">
<div class="row">
<div class="col-md-12 col-lg-12">
<h1>All Clients</h1>
</div>
</div>
<div class="row"><div class="col-md-12 col-lg-12">
{{#link-to 'clients.new' class="btn btn-info add-btn"}}
<i class="fa fa-plus"> Add new client</i>
{{/link-to}}
</div></div>
<div class="row">
<div class="col-md-12 col-lg-12">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
{{#each item in model}}
<tr>
<td>{{#link-to 'client' item.hash}}{{item.name}}{{/link-to}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</script>
Ok, just following this up since I've sorta kinda fixed it.
this.resource('client', { path: 'clients/:client_hash' }, function(){
This line did more than I thought. I thought it was more of a defining placeholder, like in Laravel.
Route::get('user/{id}', function($id)
The name used, whether it's {id} or {hash} or {poopypants} doesn't matter because it's being defined and used at that time.
I changed it to this:
this.resource('client', { path: 'clients/:client_id' }, function(){
That lets the default link-to helpers work, rather than simply getting "undefined" like they were for everything else I tried. The name of that segment is actually meaningful, it is used to derive the actual values for the segment.
With this done I was able to refactor the loop code slightly, fixing the helper.
{{#each item in model}}
<tr>
<td>{{#link-to 'client' item}}{{item.name}}{{/link-to}}</td>
This could also be refactored down more.
{{#each}}
<tr>
<td>{{#link-to 'client' this}}{{name}}{{/link-to}}</td>
Note that {{#link-to 'client' this}} works, while {{#link-to 'client' this.id}} mostly works, but gets the bug stated in the OP. A bug that I believe has taken me three DAYS to fix.

Change Navbar based on login state

I’ve been trying, using Rails/Ember pre-4, to do a fairly typical thing, that is have a page with a navbar and a content section. The navbar only changes on login (shows logout button when logged in and login and register buttons when logged out), not on every page change.
At first thought i could do something in the application.hbs template such as:
{{view navbar}}
{{outlet}}
where i set up navbar to respond to login state changes (managed by a state manager). This didn’t seem to work.
Then i tried something like (also in application.hbs):
{{outlet navbar}}
{{outlet}}
and tried setting navbar in each route, which results in lots of duplication and also didn’t ultimately work.
Before posting code, wanted to know if anyone already has a good solution to this common situation where certain parts of your page such as a navbar or sidebar only change upon some change in app state, not on every page change.
There are lots of ways to get this done. The first approach you described is closest to what we are doing. In past ember versions we used view helper for this, today we use {{render}} but it's the same basic concept. For example, application.hbs might look like this:
{{render navbar}} {{outlet}}
Now navbar.hbs can use a simple {{#if}} helper to swap links based on login state.
<div class="navbar">
<div class="navbar-inner">
{{#linkTo index class="brand"}}My App{{/linkTo}}
<ul class="nav">
<li>{{#linkTo index}}Home{{/linkTo}}</li>
<li>{{#linkTo about}}About{{/linkTo}}</a></li>
</ul>
<ul class="nav pull-right">
{{#if isAuthenticated}}
<li><a {{action logout}} href="#">Logout</a></li>
{{else}}
<li><a {{action login}} href="#">Login</a></li>
{{/if}}
</ul>
</div>
</div>
Now we add logic to NavbarController that tracks and manages login state.
App.NavbarController = Ember.ArrayController.extend({
isAuthenticated: false,
login: function() {
this.set('isAuthenticated', true);
},
logout: function() {
this.set('isAuthenticated', false);
}
});
In a real app NavbarController would proxy these requests to another controller, perhaps currentUserController. I've created a working sample here: http://jsbin.com/iyijaf/6/edit