How to iterate through all existing users in a Meteor template? - javascript

I am trying to get all the users to be iterated on my home page template, but I'm having troubles getting it to work. I've been trying so many different techniques but this is what I've got now:
Server:
Meteor.publish('userList', function() {
return Meteor.users.find({}, {fields: {username: 1, emails: 1, profile: 1}});
});
Routing:
Router.route('/', {
name: 'home',
template: 'home',
waitOn: function() {
return Meteor.subscribe('userList');
},
data: function() {
return Meteor.users.find({});
}
});
HTML:
<template name="home">
<h1>Home page</h1>
{{#each userList}}
<p>Test</p>
{{userList.username}}
{{/each}}
</template>
I think my problem actually lies in the {{#each}} block because I don't know what to call there. Not even the test text displays.

One way to solve your problem is to return {userList: Meteor.users.find()} in your data function:
Router.route('/', {
name: 'home',
template: 'home',
waitOn: function() {
return Meteor.subscribe('userList');
},
data: function() {
return {userList: Meteor.users.find()};
}
});
Then, you could iterate through userList by changing your home template to:
<template name="home">
<h1>Home page</h1>
{{#each userList}}
<p>Test</p>
{{username}}
{{/each}}
</template>

Related

vue router params on data change

I have a splitted interface like you can see it in the following example image. On the left you can see the app.vue content. On the right the router-view content. With the menu bar on the top of the app.vue content you can switch between the different router-link and change therefore the router-view on the left side. so far so good.
But now the problem: in my app.vue there are user inputs which are stored in data variables. The user input is part of the app.vue content but is also needed in the router-view.
My current version sends the user input with router-link params to the router view. The problem is that on page load and when the user input changes the data on the router view is deprecated. To show the correct data again I have to trigger the router links.
App.vue:
<template>
<div>
<router-link :to="{ name: 'route01', params: { data: userinput } }">
01 route
</router-link>
<router-link :to="{ name: 'route02', params: { data: userinput } }">
02 route
</router-link>
</div>
</template>
<script>
export default {
data: function() {
return {
userinput: 'foo',
}
}
}
</script>
route01.vue:
<template>
<div class="container">
<h1>{{userinput}}</h1>
</div>
</template>
<script>
export default {
data: function() {
return {
userinput: 'no input',
};
},
created: function() {
this.userinput = this.$route.params.userinput;
}
}
</script>
How can I reload the router view everytime the user input changed? And How can I send the default user input value on page load to the default router link?
If you make your userinput an object it will be passed by reference. That way any updates made to this object would be reflected in any component that holds a reference to the same object ..
App.vue
<template>
<div>
<router-link :to="{ name: 'route01', params: { userinput } }">
01 route
</router-link>
<router-link :to="{ name: 'route02', params: { userinput } }">
02 route
</router-link>
</div>
</template>
<script>
export default {
data: function() {
return {
userinput: { text: 'foo' },
}
}
}
</script>
route01.vue
<template>
<div class="container">
<h1>{{ userinput.text }}</h1>
</div>
</template>
<script>
export default {
data: function() {
return {
userinput: { text: 'no input' },
};
},
created: function() {
this.userinput = this.$route.params.userinput;
}
}
</script>

Vue2 & $refs & Cannot read property 'msg' of undefined

I use $refs to bind the child component but Can not get the value of child component from parent component thorough $ref.refname.msg. (I have tried $children which could work).
msg of child component has been defined.
msg info could be got through parent.$chidren.msg.
But the error showed that:
Uncaught TypeError: Cannot read property 'msg' of undefined.
Here's HTML code.
<template id="parent-component" ref='parent'>
<div>
<child-component1></child-component1>
<child-component2></child-component2>
<button v-on:click="showChildData">Show child component data</button>
</div>
</template>
<template id="child-component1" ref="cc1">
<div>
<span> This is child component 1.</span>
<button v-on:click="showParentData">Show parent component data</button>
</div>
</template>
<template id="child-component2" ref="cc2">
<div>
<span> This is child component 2.</span>
<button v-on:click="showParentData">Show parent component data</button>
</div>
</template>
<div id="e15">
<parent-component></parent-component>
</div>
Here's JavaScript:
Vue.component('parent-component',{
template: '#parent-component',
components: {
'child-component1': {
template: '#child-component1',
data: function(){
return {
msg: 'This is data of cc1'
};
},
methods: {
showParentData: function(){
alert(this.$parent.msg);
}
}
},
'child-component2': {
template: '#child-component2',
data: function() {
return {
msg: 'This is data of cc2',
num: 12
};
},
methods: {
showParentData: function(){
alert(this.$parent.msg);
}
}
}
},
data: function() {
return {
msg: 'This is data of parent.'
};
},
methods: {
showChildData: function(){
for(var i=0;i<this.$children.length;i++){
alert(this.$children[i].msg);
// console.log(this.$children[i]);
}
//!!!!This line doesn't work!!!
alert(this.$refs.cc2.msg);
}
}
});
var e15 = new Vue({
el: '#e15'
});
Code in JSFaddle
You should put ref="xx" on the child components, not the templates.
<child-component1 ref="cc1"></child-component1>
<child-component2 ref="cc2"></child-component2>
Templates are just templates, the parent component cannot ref to them.
Here is the official document for the usage of ref: https://v2.vuejs.org/v2/guide/components.html#Child-Component-Refs

meteor template: parse html content

I saved some HTML-content in my collection. By using IronRouter data() will be used to set the cursor/array. In this example I just show an example array.
Now the HTML-content isn't shown correctly, as it doesn't get parsed. The user would see the HTML-tags. What do I have to do to get the content displayed correctly?
IronRouter
Router.route('/article/:_id', {
name: 'article',
data: function () {
var articles = [{ title: 'title', content: '<strong>content</strong>'}];
return { articles: articles };
}
});
template
<template name="article">
{{#each articles}}
<h1>{{title}}</h1>
<section>{{content}}</section>
{{/each}}
</template>
Use Handlebars triple-stash:
<template name="article">
{{#each articles}}
<h1>{{title}}</h1>
<section>{{{description}}}</section>
{{/each}}
</template>

Meteor: How to make two views - listing and article

What would be the best way in meteor for creating a template for using two different views? Let's call the template 'article' and by default there should be a list of all articles with an input field to create/add new elements. When selecting an article, the selected one should be displayed.
So right now what I am trying is this:
package.js:
Package.onUse(function(api){
api.versionsFrom("METEOR#1.1.0.3");
api.addFiles([
'lib/client/templates/article.html',
], ['client']);
});
router.js:
Router.route('/article/:_id?', {
name: 'article'
})
templates/article.html:
<template name="article">
<form><input name="createNewArticle" type="text"></form>
<ul><li>List of articles</li></ul>
</template>
<template name="article_detail">
<p>Content of article</p>
</template>
If you wish to redirect to a new page, make sure you have two separate routes (one for the list of all articles and another for the the single article or article detail)
lib/router.js
Router.route('/articles', {
name: 'articles',
waitOn: function () {
return [
Meteor.subscribe('articles'),
];
},
data: function() {
return {
articles: Articles.find({})
}
}
});
Router.route('/article/:_id', {
name: 'article',
template: 'article',
waitOn: function () {
return [
Meteor.subscribe('article', this.params._id),
];
},
data: function () {
return {
article: Articles.findOne({
_id: this.params._id
})
};
}
});
client/templates/article.html:
<template name="articles">
<form><input name="createNewArticle" type="text"></form>
<ul>
{{#each articles}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
<template name="article">
<p>{{title}}</p>
</template>
Make sure you setup your publications too in server/publications.js

How render a route relevant subheader with meteor blaze?

The end result of all of what I am about to go over is the subheader is not rendering on screen like i want it to.
Currently there is a mongo collection subheader with a category field and a texth field.
Subheader = new Mongo.Collection('subheader');
Meteor.methods({
subheaderInsert: function(subheaderIdAttributes) {
check(String);
check(subheaderIdAttributes, {
texth: String,
category: String
});
var subheaderId = _.extend(postAttributes, {
submitted: new Date()
});
var subheaderId = SubheaderId.insert(subheader);
return {
_id: subheaderId
};
}
});
There is a route that subscribes to the subheader and other page data.
Router.route('/', {
name: 'home',
controller: MissionstatementpostController,
waitOn:function () {
return Meteor.subscribe('subheader', 'home');
}
});
The publish function appears to work fine.
Meteor.publish('subheader', function(cat) {
return Subheader.find({category: cat});
});
The correct doc from the mongodb collection is reaching the client. this can be seen by
Subheader.findOne(); output Object {_id: "NPo5cwqgjYY6i9rtx", texth: "ex text", category: "home"}
The problem starts here
The template loaded by the Controller in this case MissionstatementpostController is postlist
<template name="postsList">
<div class="posts page">
{{> subheader}}
<div class="wrapper">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
{{#if nextPath}}
<a class="load-more" href="{{nextPath}}">Load more</a>
{{else}}
{{#unless ready}}
{{> spinner}}
{{/unless}}
{{/if}}
</div>
</template>
Here is the subheader template
<template name="subheader">
<div class="container">
<p>{{{texth}}}</p>
</div>
</template>
So what did I mess-up?
thanks
you must create a template helper for your subheader template. To return just the texth field, the helper will be like this.
Template.subheader.helpers({
texth: function() {
var sh = Subheader.findOne();
return sh && sh.texth;
}
});
You can return the whole document and use the #with helper inside the template.
Template.subheader.helpers({
subh: function() {
return Subheader.findOne();
}
});
<template name="subheader">
{{#with subh}}
<div class="container">
<p>{{{texth}}}</p>
</div>
{{/with}}
</template>
You can find more info about template helpers on Meteor Docs.

Categories