Iron Router cannot find a path that I'm pretty sure is defined correctly. The path name shows up as valid and exists in my meteor shell, but it returns as "undefined" in my Chrome console. Here's the template declaration:
<template name="vidPreview">
<div class="videoPreview">
<h2>{{title}}</h2>
Play
<p>Created At: {{createdAt}}</p>
{{#if isLive}}
<p>LIVE</p>
{{/if}}
<p>Viewers: {{uniqueViewers}}</p>
<p>Views: {{views}}</p>
<p>Location: {{location}}</p>
<ul>
{{#each genres}}
<li><p>{{this}}</p></li>
{{/each}}
</ul>
<p>Created by: {{creator}}</p>
</div>
</template>
And here's the route declaration:
Router.route('/video/:_id',{
name: 'singleVideo',
template: 'singleVideo',
layoutTemplate: 'singleVideo',
data: function(){
var currentVideo = this.params._id;
return Videos.findOne({ _id: currentVideo });
},
action: function(){
this.render('singleVideo');
}
});
There are no helpers operating on the vidPreview template. The data context is that of an individual Video object, and this template gets placed multiple times into a parent template. Help is greatly appreciated.
I thought the route name parameter in pathFor was positional, i.e.
{{pathFor 'singleVideo' _id=this._id }}
"We can pass data, query and hash options to the pathFor helper."
Try:
{{pathFor route='singleVideo' data={ _id: this._id} }}
Related
So I have two collections, appliers & profiles,
appliers = {_id,idAppliersProfile}
&
profile = {_id,profilename}
So my question is if I do an #each for appliers, how do I access profile collection to get the profile instead of just the id?
Thanks.
Assuming both sets of docs are published to the client, one solution looks something like this:
html
<template name="myTemplate">
{{#each appliers}}
{{#with getProfile idAppliersProfile}}
<div>{{profilename}}</div>
{{/with}}
{{/each}}
</template>
js
Template.myTemplate.helpers({
appliers: function () {
return appliers.find();
},
getProfile: function (id) {
return profile.findOne(id);
}
});
I am digging into Ember and am trying to serve a list of content to my route model. Here is my App.js code:
var App = Ember.Application.create({});
App.Router.map(function() {
this.route('about');
this.resource('blogs');
this.resource('projects');
});
App.PROJECTS = [
{
"id": 1,
"title": "SnapFoo - SVG Animation Library",
"textone": "SnapFoo",
"texttwo": "SVG Animation Library",
"image": "snapfoo.jpg"
}
];
App.ProjectsRoute = Ember.Route.extend({
model: function() {
return App.PROJECTS;
}
});
The PROJECTS array is abbreviated in terms of content but that's the format. Now, I am trying to run my each loop in the Hanldebars template like this:
<script type="text/x-handlebars" data-template-name="projects">
{{#each}}
<div class="project-icon">
<span>{{textone}}</span>
<span>{{texttwo}}</span>
<img {{bind-attr alt="title" src="image"}}/>
</div>
{{/each}}
</script>
However, when doing this, the error I receive is
Uncaught TypeError: Cannot read property 'addDependency' of undefined coming from ember.min.js.
If I remove the {{each}} loop, the error goes away which leads me to believe this has something to do with the model in the route. But any advice would be very helpful. Thanks!
You are missing the model in your view, you are iterating over nothing {{each}}
You need put your variable in this case your model.
<script type="text/x-handlebars" data-template-name="projects">
{{#each model as |project|}}
<div class="project-icon">
<span>{{project.textone}}</span>
<span>{{project.texttwo}}</span>
<img {{bind-attr alt="title" src="image"}}/>
</div>
{{/each}}
</script>
I have created an example where you can see as this code work, it's very similar what you want achieve.
Demo: http://jsbin.com/zexopa/1/edit?html,js,output
I use the query parameters in my application. And the queryParameters are 'name' and 'category'.
The 'name' parameter is used in the select and the 'category' uses the input, but there is something wrong with the select 'name' if I set it default to null.
If I change the 'name', the 'name' always is undefined in the url.
Route:
App.IndexRoute = Ember.Route.extend({
beforeModel: function() {
this.controllerFor('index').set('products', [1,2,3]);
},
model: function() {
return [{'is_active':false, 'name':'One'}, {'is_active':false, 'name':'Two'}, {'is_active':false, 'name':'Three'}, {'is_active':false, 'name':'Four'},{'is_active':false, 'name':'Five'}];
},
actions: {
queryParamsDidChange: function() {
this.refresh();
}
}
});
Controller:
App.IndexController = Ember.Controller.extend({
queryParams: ['name', 'category'],
name: null,
category: null
});
Template:
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view "select" content=products value=name prompt="all"}}
{{input type="text" value=category class="form-control"}}
<ul>
{{#each model as |item|}}
<li>{{item.name}}</li>
{{/each}}
</ul>
</script>
Can you help to check what happens to my application?
Query params must be string to be properly binded. Your input works, as the value is String object. In name array you provided Integer. Unfortunately, I have not found any mention about that in docs, but you can see a working demo here: http://jsbin.com/lixili/1/edit?html,js,output
If I can give you some tip about your code:
beforeModel is not a place for setting controller properties, do it in setupController method as in JSBin provided
You did not defined query params in route, but you could and get rid of the queryParamsDidChange
Hope I helped!
I want to implement a system that shows me the newest posts. For this I do not want to use the index action from the user as this is already taken for another post function but a "newest" action. It is showed on the index route with a {{ render "postNewest" }} call. I would prefer to load the data in the PostNewestController or PostNewestView instead of the route for abstraction reasons.
I tried two ideas to achieve this, but none worked so far:
create a custom adapter and add a findNewest() method: the findNewest() method is sadly not found when trying to call in the init method of the controller.
write the request directly into the init method and then update with store.loadMany(payload): data is successful request. However, I do not know how to access the data from the template and set the content of the controller.
Is there any way for this?
EDIT:
Here is the source code to better understand the problem:
PostModel.js
App.Post.reopenClass({
stream: function(items) {
var result = Ember.ArrayProxy.create({ content: [] });
var items = [];
$.getJSON("/api/v1/post/stream?auth_token=" + App.Auth.get("authToken"), function(payload) {
result.set('content', payload.posts);
});
return result;
}
});
PostStreamController.js
App.PostStreamController = Ember.ArrayController.extend({
init: function() {
this.set("content", App.Post.stream());
},
});
index.hbs
{{# if App.Auth.signedIn}}
{{ render "dashboard" }}
{{else}}
{{ render "GuestHeader" }}
{{/if}}
{{ render "postStream" }}
postStream.hbs
{{#each post in model}}
<li>{{#linkTo 'post.show' post data-toggle="tooltip"}}{{post.name}}{{/linkTo}}</li>
{{else}}
Nothing's there!
{{/each}}
PostShowRoute.js
App.PostShowRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
},
setupController: function(controller, model) {
controller.set('content', model);
},
});
I Had this issue too. Just add init in your controller, and define the model you want to get there.
In your Controller
App.PostRecentController = Ember.ArrayController.extend({
init: function() {
return this.set('content', App.Post.find({
recent: true
}));
}
});
In your template
{{#each post in content}}
{{post.body}}
{{/each}}
I would recommend you check EMBER EXTENSION, it will give you a good idea of the naming, and see if everything is missing.
I figured out the problem. The Post model has a belongsTo relationship to another model. This relationship is not loaded by Ember so in the stream() method I have to load this manually. Then everything works as expected.
Lets say I have this 'Model'
var lists = [
{
title: 'Default title',
image: '/img/default.jpeg',
section: [
{ name: 'Default Name',
description: 'Default Description'
}
],
activity: ['default']
}
];
Here is the view templates
<template name="main_list_view">
{{#each list.section}}
{{> section}}
{{/each}}
<a id="addSection" href='#'>Add Section</a>
</template>
<template name="section">
<li>{{section.name}}</li>
<li>{{section.description}}</li>
<a class="deleteSection" href='#'>Delete Section</a>
</template>
I need help w the logic for add more sections and remove a specific section from the colection.
I have checked mongoDB and looks like I have to use something like addToset and $unset for update the model, but I really only want to remove them from the view, cause I want the default model to remain the same always.
So how I remove and add Templates to the view when the user clicks Addcontent, and remove the specific view when the user clicks remove ? is there a Meteor way to do it ? So a user clicks addContent and a new section template is rendered or removed if clicks remove.
Removing one should be simple enough. First, it might help to add the id of the section in your delete link:
<a data-id="{{section._id}}" class="deleteSection" href='#'>Delete Section</a>
Template.section.events({
'click a.deleteSection': function(evt) {
Sections.remove($(evt.target).data('id'));
}
});
Adding one is a different story, because it depends on exactly what you want to happen when you click the addSection link. Does that link render a form that creates a new Section on submission? Or does the handler to that link create a Section object and fill in the values?
Edit
It was pointed out that Sections is not a collection. I should've seen that. Making it into a collection would be an obvious way to deal with that. So instead of:
{{#each list.section}}
{{> section}}
{{/each}}
You'd have:
{{#each sections list._id}}
{{> section}}
{{/each}}
And in your js file:
Template.main_list_view.helpers({
sections: function(list_id) {
return Sections.find({ list_id: list_id });
}
});
Alternatively, you could move the "section" template up to the parent and then you could add the list_id as a data attribute on the link::
{{#each list.section}}
<li>{{name}}</li>
<li>{{description}}</li>
<a data-id="{{list._id}}" data-name="{{name}}" data-description="{{description}}" class="deleteSection" href="#">Delete Section</a>
{{/each}}
Then in your js file:
Template.section.events({
'click a.deleteSection': function(evt) {
var list = Lists.find($(evt.target).data('id'));
var section = { name: $(evt.target).data('name'), description: $(evt.target).data('description') };
sections = list.sections;
sections.splice(sections.indexOf(section), 1);
Lists.update(list._id, $set: { sections: sections });
}
});