I am working on a Meteor application and am trying to pass an attribute of an item in a collection to a javascript function. In this instance I working with instafeed.js, a javascript plugin for the instagram API, but I would like to understand the process on a more fundamental level.
I’ve been able to pull records from my Teams collection into the /teams/:id route
, and display attributes of a team using the {{name}}
and {{igHandle}}
template helpers.
I have also been able to get instafeed.js to work, using this package etjana:instafeed and the demo provided online. The tag I am pulling is assigned statically via:Session.setDefault(‘tagName’,’football’);
Eventually I would like to pull the user profiles, but that requires an access token from oauth2. I think that can be achieved with a {{$.Session.get access_token}}
handlebar helper, but I need to figure out to feed a variable into the instafeed.js function first.
Could someone please explain how to pass the {{igHandle}} attribute through to the tagName in the javascript function. My code is as follows:
Team Template:
<template name="teamView">
<div class=“ui container”>
<h3>{{name}}</h3>
<p>
<i class="fa fa-instagram fa-lg"></i>
<a target="_blank" href="http://instagram.com/{{insta_hndl}}"> {{insta_hndl}}</a>
</p>
<br>
<h3>Instagrams</h3>
{{> igTeamFeed}}
</div>
</template>
Everything works, except the {{>igTeamFeed}} render. I am able to get content to show, but it is currently static. (assigned via (Session.setDefault('tagValue','football')
.
Instafeed Template:
<template name="igTeamFeed">
<div class="ui container”>
<h3>@{{insta_hndl}} Instagram</h3>
<div id="instafeed"></div>
</div>
</template>
Content is displaying, but again only through the static (Session.setDefault('tagValue','football')
code.
Router:
Router.route('/teams/:_id', {
name: 'teamView',
template: 'teamView',
data: function(){
var currentTeam = this.params._id;
return Teams.findOne({ _id: currentTeam });
},
action: function() {
if (this.ready()) {
this.render('teamView');
} else {
this.render('loading');
}
}
});
Works with template helpers, so I am thinking I am ok here. Also following the instructions of a user per one of my prior posts.
Instafeed Javascipt: (needs some work)
Template.igTeamFeed.helpers ({
igData: function() {
return Session.get('insta_hndl');
},
});
Template.igTeamFeed.onRendered(function () {
//clear any previously stored data making the call
Session.get('insta_hndl'); //extra add-in
Session.set('insta_hndl', null);
Session.set('insta_hndl', this.data.insta_hndl); //extra add-in
var igHandle = this.data.insta_hndl;
});
Tracker.autorun(function(){
feed = new Instafeed({
get: 'tagged',
tagName: Session.get('insta_hndl'),
clientId: ‘xxxxxxxxxxxxxxxxxxx’,
resolution: 'thumbnail',
sortBy: 'most-liked',
limit: '15'
});
feed.run();
});
insta_hndl
for the session. The session item is passed through the team/:_id
tag of the url, and defined in the routeronRendered
is wiping out the old handle, and inserting the new one. I added two additional Session.get
and Session.set
functions since I was getting an error that insta_hndl
was undefined (differing from the response on my previous post). Could be wrong there. tracker.autorun
function was code I had working with an instafeed example. Should it be somewhere else? Maybe in a helper
or onRendered
function? Also do I need tracker.autorun
to use instafeed? To my understanding it dynamically updates the feed when a tagName
changes, but aren't there other ways to do this?How to Solve These are some ways I'm thinking I could to solve this. Please advise on how to do this / what you think is best practice:
Teams.findOne().insta_hndl
but didn't have much luck. Is that the right code block to use? Do I have to define a variable in the template helper, or can I call it directly in the feed js function?If someone could help me get this working that woudld be great, but explanations would even better! Really spending a lot of time on this, and many of the online resources are using depreciated syntax.
Also two more related questions questions:
Should I use a controller? Should i write out a controller separately? Or just include it in Router.route
functions? Seeing some people rely heavily on controllers, but a lot of documentation does everything through Router.route
.
Should I break out the instafeed function into a method
? If so how should I do this? I spent a great amount of time tryig to set up the whole instafeed function as a server side method, but couldn't seem to get it to work. I only foresee myself using this function in one or two other templates, so I figured it was fine to leave as is. Please advice.
Sorry that this was a bit confusing. The correct javascript is:
Template.igTeamFeed.helpers ({
teams: function() {
return Teams.find();
}
});
Template.igTeamFeed.onCreated( function() {
var igHandle = Teams.findOne(Router.current().params._id).insta_hndl;
feed = new Instafeed({
get: 'tagged',
tagName: Session.get('insta_hndl'),
clientId: ‘xxxxxxxxxxxxxxxxxxx’,
resolution: 'thumbnail',
sortBy: 'most-liked',
limit: '15'
});
feed.run(); //run the new Instafeed({})
});
There is no need for any of the things I suggested. The attribute can be grabbed with Collection.findOne(Router.current().params._id).attrib, where Collection is your collection and attrib is the non-_id value you want to grab.
Also did not need tracker.autorun, that was throwing me off as well.