Get current route name on handlebar template in Ember.js 2 - javascript

I needed to know the current route name so I can show or hide a global component that is created on my application.hbs.
This component should be hidden in just one route template, so this looks like the easier solution to me. Getting the current route name and if its equal "posts" it will not show the header-bar component.
Something like this:
{{#if currentRoute != 'login'}}
{{header-bar}}
{{/if}}
{{outlet}}
Any idea on could I achieve this or something similar that solves my problem?

applicatiion controller has a property names currentRouteName. You can use it.
If you want to use in another template you need to define that in controller.
test.js (controller)
init(){
this._super(...arguments);
let appCtrl = Ember.getOwner(this).lookup('controller:application');
this.set('appCtrl', appCtrl);
}
test.hbs
{{appCtrl.currentRouteName}}

Same answer as Ebrahim Pasbani.
This syntax is still usable in latest Ember version:
App.__container__.lookup('controller:application').currentRouteName;

Related

Ember.js computed property to return model ID array?

Updated: 11:36PST 07 Dec 2017
All I'm trying to do is create an array containing a list of current ID's in the model to use in a child component, but somehow seem to be missing something obvious. If it is relevant, I am using Ember 2.17.0 with Ember Data 2.17.0 as well.
The route returns an array of models very similar to a findAll, but modified to work with a REST endpoint I do not have any control over. I need an array of the id's from the model to use in a component embedded in the route. Based on feedback, I have attempted to implement this in both the route and the controller.
In the controller, I'm trying it this way.
searchIdArrayC: computed('model', () => {
return this.get('model').map((record) => record.get('reachId'));
})
..and in the route I'm trying it this way.
searchIdArrayR: computed('model', () => {
return this.modelFor('reaches').map((record) => record.get('reachId'));
});
When I look at it in the Chrome Ember Inspector, for both the route and controller it is telling me Error while computing: searchIdArrayR or Error while computing: searchIdArrayC.
Just to try and do some testing, I sent both the route and the controller to the console. With both the route and controller, the aforementioned methods are working, so I am really confused.
Thank you in advance for any help or guidance you may be able to offer.
In route file, model is a function, but you are treating it like model property which is available in the corresponding controller.
If you can move searchIdArray computed property to corresponding controller then that should work.

Redirect to different route in Meteor if a object doesn't exist

I have a route postDetail with path /posts/:postId using Flow Router.
I want to check if the post actually exists. If the post doesn't exists, I want to show the postList route instead.
How can I do this? I guess I can use triggersEnter; however, the data is subscribed in the template, so maybe I cannot use triggersEnter in the router.
A simple way would be to populate the template with a variable doesExists from the template helper, and just use
{{#if doesExists}}
[...]
{{else}}
{{> postList}}
{{/if}}
but I do not think it's a very smart way to do it because I have to do this in a lot of different templates and I am not able to redirect the user to the postList route with this approach.
If you have Template level subscriptions like:
Template.YOUR_TEMPLATE_HERE.onCreated(function() {
let self = this;
self.autorun(function() {
self.subscribe('posts');
})
});
Then you can redirect with triggersEnter like so:
triggersEnter: [function(context, redirect) {
if (Posts.find({_id:context.params.id}).count() < 1)
redirect('/postslist');
}],

Load one template into a another one in Ember.js

Within one of my route's renderTemplate method, I've tried to render a different template by using this.render:
App.IndexRoute = Ember.Route.extend({
renderTemplate: function() {
this.render( 'dashboard', {
into: 'admin'
});
}
});
But the application within the browser is empty and the console shows the following:
Assertion Failed: You attempted to render into 'admin' but it was not
found
After this error message, I thought that the "admin" template might simply not be existent, but it it's there. Both the "dashboard" and the "admin" template are loaded. And the weirdest thing: I'm able to use this.render( 'dashboard' ) and this.render( 'admin' ) and both of them work fine.
What am I doing wrong? I've even added an {{outlet}} tag to the "admin" template.
If you want to render into admin then you have to use named outled inside your template (associated with route file you write renderTemplate). So, inside your template use:
{{outlet 'admin'}}
edit
I'm not really sure what to do right now. Just to clarify: "admin" is
a hbs template which contains a {{outlet}}. And into this outlet tag,
I want to load 'dashboard.hbs'. And after that, I want to output the
whole thing.So in which file do I need
I'm assuming you want to render these 2 templates from another unassociated route. In that case you could add {{partial 'dashboard'}} to admin.hbs and use just this.render('admin') in your IndexRoute.
edit 2
Inside your IndexController specify partialName: 'dashboard' and change it dynamically in your code and replace {{partial 'dashboard'}} with {{partial partialName}}. It should work dynamically and you can swap out dashboard for another templates.

How do you render multiple templates with one route controller using iron-router?

URL to current version of my project
Here is the code for my project
Background:
I am making a blog using meteor and iron-router. I want to use a single controller for several different "category pages," which filter a list a blog articles in the yield region.
The Problem:
The article list does not get rerendered when the URL changes. I.e. the article list is not reactive. Interestingly, if I navigate back to the home page, the correct article list shows up.
The Question:
How do I make that article list change when I change between different routes on the category route controller?
Some example code:
Please note that the code for this whole project is available here.
Here is my Route Controller:
CategoryController = RouteController.extend({
action: function(){
this.render();
},
template: 'category',
data: function(){
return {category: this.params.category};
}
});
CategoryController.helpers({
articles: function(){
return Articles.find({category: this.params.category});
}
});
And here is the template it is rendering:
<template name='category'>
<div class="container">
<h2>{{category}}:</h2>
<ul>
{{#each articles}}
<li>
{{#linkTo route="article.show"}}
{{title}}
{{/linkTo}}
</li>
{{/each}}
</ul>
</div>
</template>
Resources/Updates:
Read this article on Meteor Reactivity and the Deps Package. Very interesting, but after trying some Deps.autoruns in different places, I don't think that this is the answer.
Currently trying to make different "category" routes inherit from the controller.
The article list does not change because the Template helper is not using a reactive data source. You may use the RouteController.getParams method to establish a reactive dependency on route parameters as shown below.
CategoryController.helpers({
articles: function(){
var controller = this;
var params = controller.getParams();
return Articles.find({category: params.category});
}
});
From Iron Router documentation:
Note: If you want to rerun a function when the hash changes you can do
this:
// get a handle for the controller.
// in a template helper this would be
// var controller = Iron.controller();
var controller = this;
// reactive getParams method which will invalidate the comp if any part of the params change
// including the hash.
var params = controller.getParams();
By default the router will follow normal browser behavior. If you
click a link with a hash frag it will scroll to an element with that
id. If you want to use controller.getParams() you can put that in
either your own autorun if you want to do something procedural, or in
a helper.

Emberjs: How to render a view with the view name in variable?

i would like to add some cards to a board, all cards are very different. so i want to create different view for each card that can bind different events and template. I set a 'type' property in the card model which to distinguish the cards.
the board template look like below:
{{#each card in cards}}
{{render card.type card class="card"}}
{{/each}}
However, the first argument for the render help can not be a variable, it can only be the card view name string.
anyone know how to achieve this?
As you already mentioned the built-in render helper only accepts a string to lookup the template to render, therefore one possible solution would be to write your own custom render helper, which then after getting the correct name with card.get('type') delegates the rendering to the built-in render helper. This could look something like this:
Ember.Handlebars.registerBoundHelper('renderCard', function(context, card, options) {
return Ember.Handlebars.helpers.render.call(context, card.get('type'), 'card', options);
});
After that, you could use it like this in your template:
{{#each card in cards}}
{{renderCard this card}}
{{/each}}
Edit
I've also added a basic jsbin that shows it working.
Edit 2
Edited the jsbin again, using object data to be rendered into the template, see here.
Edit 3
Lamentably the DS.FixtureAdapter does not support embedded records which is what you need to make it work. But you could configure you orignal DS.RESTAdapter like this:
App.Adapter = DS.RESTAdapter.extend();
App.Adapter.map('App.Dashboard',
cards: {embedded: 'always'}
);
App.Store = DS.Store.extend({
adapter: App.Adapter
});
This way the card records are always loaded with the parent record. I guess doing this change would make the call to card.get('type') in you handlebar helper return the value rather then undefined.
Hope it helps.
For Ember 1.9 solution above doesn't work. Use another way to register helper:
Ember.Handlebars.registerHelper 'renderDynamic', (context, model, options)->
contextString = options.hash.contextString
model = options.data.view.getStream(model).value()
return Ember.Handlebars.helpers.render(model.get('type'), contextString, options)
And in the template:
= hb 'renderDynamic "this" currentModel contextString="curremtModel"
or in handlebars:
{{renderDynamic "this" currentModel contextString="curremtModel"}}

Categories