Meteor Subscribe & Publish with external api - meteor

I'm trying to connect my Meteor Subscribe and Publish to my api, the Publish is calling the API and returning the data no problem but I cant seem to load my data on the template.
Below is my code.
boards.js
import './boards.html';
Tracker.autorun(function() {
Meteor.subscribe('getUserBoards');
});
boards.html
<template name="userBoards">
{{#each boards}}
{{this.id}}
{{/each}}
</template>
index.js
if (Meteor.isServer) {
Meteor.publish('getUserBoards', function getBoards() {
var self = this;
try {
var response = HTTP.get(Meteor.settings.private.api.url+'users/'+this.userId+'/boards/');
_.each(response.data.boards, function(item) {
var doc = {
id: item._id,
name: item.name,
urlFriendlyName: item.urlFriendlyName,
access: item.access,
backgroundImage: item.backgroundImage,
products: item.products,
sharedCount: item.meta.shared,
totalProducts: item.meta.totalProducts,
dateAdded: item.meta.dateAdded
};
self.added('boards', item._id, doc);
});
self.ready();
} catch(error) {
console.log(error);
}
});
}

your html template:
<template name="userBoards">
{{#each boards}}
{{this.id}}
{{/each}}
</template>
You need a helper to return a cursor called boards:
js:
Template.userBoards.helpers({
boards(){
return Boards.find();
}
});

Related

Can't send data context to template via Iron Router in Meteor

This is my router:
Router.route('/cource/:courcePath', {
name: 'Cource_page',
template: 'Cource_page',
data() {
return Cources.find({ courcePath: this.params.courcePath });
}
});
Template:
<template name="Cource_page">
<div class="container">
{{#each cources}}
<h1>{{courceTitle}}</h1>
{{/each}}
</div>
</template>
And helper:
Template.Cource_page.helpers({
cources() {
let courcePath = this.courcePath;
console.log(courcePath);
return Cources.find({ courcePath: courcePath });
}
});
When I go to some page (http://localhost:3000/cource/my-new-cource, for example), no data rendering and I get undefined in the console (the output of template helpers). What am I doing wrong?
You need to pass the data in the render directive
Router.route('/post/:_id', function () {
this.render('Post', {
data: function () {
return Posts.findOne({_id: this.params._id});
}
});
});
OR
you should subscribe to the data in the route:
Router.route('/cource/:courcePath', {
name: 'Cource_page',
template: 'Cource_page',
subscriptions: function() {
this.subscribe('courses', this.params.courcePath);
}
});
Check the guide for more info:
http://iron-meteor.github.io/iron-router/
When you provide the data context in your i-r route you don't need the helper. Try:
Router.route('/cource/:courcePath', {
name: 'Cource_page',
template: 'Cource_page',
data() {
return Cources.find({ courcePath: this.params.courcePath });
}
});
<template name="Cource_page">
<div class="container">
{{#each this}}
<h1>{{courceTitle}}</h1>
{{/each}}
</div>
</template>

Flow router Meteor

I'm new with this framework. I want to use flow router as it is reactive. Before this I'm using iron router. Please someone show me how to change the code to flow router as flow router has no waitOn concept and onBeforeAction(replaced by triggersEnter). Your help and kindness really appreciated.
router.js
Router.route('/EditLokasi/:_id', {
name: 'EditLokasi',
template: 'EditLokasi',
onBeforeAction: function(){
var lokasiID = Lokasi.findOne({_id: this.params._id});
this.render('EditLokasi',{data: lokasiID});
},
waitOn: function(){
if(Meteor.userId()){
var userid = Meteor.user().username;
return [ Meteor.subscribe('profiles', userid), Meteor.subscribe('login') ];
}
}
});
EditLokasi.js
Template.EditLokasi.helpers({
lokasi: function(){
return Lokasi.find({data:lokasiID});
}
});
You can use subscriptions to subscribe and then, on the template, check if the data is ready through subReady
FlowRouter.route('/login', {
name: 'login',
subscriptions: function() {
var userid = Meteor.user().username;
this.register('subscribe-to-profile', Meteor.subscribe('profiles', userid));
// do it the same for other subscribe
},
action(params) {
var lokasiID = Lokasi.findOne({_id: this.params._id});
BlazeLayout.render('EditLokasi', {data: lokasiID});
}
});
And on your template
<template name="EditLokasi">
{{# if helper_checkSubReady}}
......
{{else}}
loading....
{{/if}}
</template>
helper_checkSubReady is a helper to check if the subscriptions are ready or not (check the link I mentioned above)

Meteor publish - subscribe user profile

I'm trying to publish a user profile. I have the following publish function in publish.js:
Meteor.publish("singleProfile", function ( profileId ) {
check(profileId, String);
return Meteor.users.find(profileId, { fields: { _id: 1, services: 1, profile: 1 }});
});
This is my route in router.js:
Router.route('/profile/:_id', {
name: 'profilePage',
template: 'appProfile',
onBeforeAction: function() {
var currentUser = Meteor.userId();
if(currentUser) {
this.next();
} else {
this.render("signin");
}
},
waitOn: function() {
this.response = Meteor.subscribe('singleProfile', this.params._id);
return this.response;
},
action: function() {
this.render('appProfile');
}
});
Question is, how do I access the profile details in the appProfile template? Do I need a template helper defined? Or do I need to modify this code?
You can use a template helper for this:
Template.appProfile.helpers({
users() {
return Meteor.users.find();
}
});
Then in your template:
...
{{#each users}}
{{profile.myProperty}} <!-- Renders the myProperty field of the profile. -->
{{/each}}

MeteorJs: Return data Iron:router

Iron router return data is in template but I can't use it.
For example I have db with jobs, where every job has a position (e.g. jobs.position):
ExistJobPostController = RouteController.extend({
layoutTemplate: 'existJob',
data:function() {return Posts.findOne(this.params._id); }
})
Router.map(function() {
this.route('existJob', {
path: '/jobs/:_id',
controller: ExistJobPostController,
});
});
<template name="existJob">
{{position}}
</template>
And nothing happens, I think that it's my fault, but I really can't understand how to fix this.
Can anybody help?
You should first check that the correct data is even being set on your template data context. Here's a quick general summary of how to set the data context and how to access it from various locations:
Router.map(function() {
this.route('index', {
path: '/index',
data: function(){
var obj = {
fname: "Tom",
lname: "Smith"
};
return obj;
}
});
});
Template.index.onRendered(function(){
console.log(this.data.fname);
});
Template.index.events({
'click body': function(e, tmpl){
console.log(tmpl.data.fname);
}
});
Template.index.helpers({
lastName: function(){
return this.lname;
}
});
<template name="index">
You have to use `this` when directly accessing template data from spacebars.
{{this.firstName}}
The following comes from Template.index.helpers:
{{lastName}}
</template>

Tracker afterFlush error : Cannot read value of a property from data context in template rendered callback

I'm making a simple Meteor app that can redirect to a page when user click a link.
On 'redirect' template, I try get the value of property 'url' from the template instance. But I only get right value at the first time I click the link. When I press F5 to refresh 'redirect' page, I keep getting this error message:
Exception from Tracker afterFlush function: Cannot read property 'url' of null
TypeError: Cannot read property 'url' of null
at Template.redirect.rendered (http://localhost:3000/client/redirect.js?abbe5acdbab2c487f7aa42f0d68cf612f472683b:2:17)
at null.
This is where debug.js points to: (line 2)
if (allArgumentsOfTypeString)
console.log.apply(console, [Array.prototype.join.call(arguments, " ")]);
else
console.log.apply(console, arguments);
} else if (typeof Function.prototype.bind === "function") {
// IE9
var log = Function.prototype.bind.call(console.log, console);
log.apply(console, arguments);
} else {
// IE8
Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
}
Can you tell me why I can't read the value of 'url' property from template data context in template rendered callback?
This is my code (for more details, you can visit my repo):
HTML:
<template name="layout">
{{>yield}}
</template>
<template name="home">
<div id="input">
<input type="text" id="url">
<input type="text" id="description">
<button id="add">Add</button>
</div>
<div id="output">
{{#each urls}}
{{>urlItem}}
{{/each}}
</div>
</template>
<template name="redirect">
<h3>Redirecting to new...{{url}}</h3>
</template>
<template name="urlItem">
<p><a href="{{pathFor 'redirect'}}">
<strong>{{url}}: </strong>
</a>{{des}}</p>
</template>
home.js
Template.home.helpers({
urls: function(){
return UrlCollection.find();
}
});
Template.home.events({
'click #add': function() {
var urlItem = {
url: $('#url').val(),
des: $('#description').val()
};
Meteor.call('urlInsert', urlItem);
}
});
redirect.js
Template.redirect.rendered = function() {
if ( this.data.url ) {
console.log('New location: '+ this.data.url);
} else {
console.log('No where');
}
}
Template.redirect.helpers({
url: function() {
return this.url;
}
});
router.js
Router.configure({
layoutTemplate: 'layout'
})
Router.route('/', {
name: 'home',
waitOn: function() {
Meteor.subscribe('getUrl');
}
});
Router.route('/redirect/:_id', {
name: 'redirect',
waitOn: function() {
Meteor.subscribe('getUrl', this.params._id);
},
data: function() {
return UrlCollection.findOne({_id: this.params._id});
}
});
publication.js
Meteor.publish('getUrl', function(_id) {
if ( _id ) {
return UrlCollection.find({_id: _id});
} else {
return UrlCollection.find();
}
});
Add this
Router.route('/redirect/:_id', {
name: 'redirect',
waitOn: function() {
Meteor.subscribe('getUrl', this.params._id);
},
data: function() {
if(this.ready()){
return UrlCollection.findOne({_id: this.params._id});
}else{
console.log("Not yet");
}
}
});
Tell me if works.
With help from my colleague, I can solve the problem.
My problem comes from wrong Meteor.subscribe syntax. In my code, I forget "return" in waitOn function. This will make Meteor do not know when the data is fully loaded.
Here is the right syntax:
waitOn: function() {
return Meteor.subscribe('getUrl', this.params._id);
}

Resources