Meteor Geolocation method from Event - meteor

I want to get the latLng, but only after an event. How can this be achieved? I've tried tracker and the like but nothing has worked. The only thing that has worked is calling Geolocation.latLng(); from inside the helper, which is before the event.
Here is how I wish it would work. I've tried the same thing with Session.set() and Session.get()). I've also tried to use Tracker dependencies, but since the location isn't available immediately triggering the changed() doesn't help.
I should include that I'm using the package created by the Meteor Development Group located at https://github.com/meteor/mobile-packages/.
var location = {};
Template.Home.helpers({
'location': function() {
return location;
}
);
Template.Home.events({
'focus .location': function() {
location = Geolocation.latLng();
},
});

I like #ZuzEL's answer, but in case you really want to do it your way with Sessions:
Template.Home.helpers({
'location': function() {
return Session.get("location");
}
);
Template.Home.events({
'focus .location': function() {
Session.set("location", Geolocation.latLng());
},
});
no need for the ReactiveVar package because Sessions are like global reactive themselves :)

This is because your location is not reactive variable itself.
var location = new ReactiveVar();
Template.Home.helpers({
'location': function() {
return location.get();
}
);
Template.Home.events({
'focus .location': function() {
location.set(Geolocation.latLng());
},
});
Don't forget to include reactive var package
meteor add reactive-var
But, since you are using mdg:geolocation
And here API Doc says that every method is reactive, you can use tracker in onRendered callback whatever the location changes
Template.Home.onRendered(function(){
this.autorun(function(){
location.set(Geolocation.latLng());
})
});

Related

Client shows all collections as empty

I am having trouble getting the client to find entries in a collection in a Meteor application.
This seems to be a common question and I have tried all the suggestions I have come across. For now, autopublish is included, so as far as I can tell the problem shouldn't be with publishing/subscribing.
I even went back and went through the simple-todo tutorial on meteor.com and meticulously checked each step. As soon as I replace my array with a collection, the collection comes up empty.
All I can think to do is wipe out my meteor install and reinstall, but I would really like to know what is causing this.
printTypes = new Mongo.Collection("printTypes");
if (Meteor.isClient) {
Meteor.subscribe("printTypes");
Router.configure({
loadingTemplate: 'homePage'
});
Router.map( function () {
this.route('itemPage', {
path: '/item',
waitOn: function() {
return Meteor.subscribe('printTypes');
},
data: function () {
templateData = { printTypes: printTypes.find({}) };
return templateData;
}
});
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
Meteor.publish("printTypes", function () {
return printTypes.find();
});
});
}
Any ideas? Thanks!

Meteor helper doesn't refresh on Reactive var .set()

I update reactive var on autorun. The same reactive var is used in helper. But helper values doesn't refresh by autorun function. My below code will explain you clearly.
Template.home.onCreated(function () {
var self = this;
self.ITEMS_INCREMENT = 2;
self.itemsLimit = new ReactiveVar(2);
});
Template.home.onRendered(function () {
var self = this;
this.autorun(function(){
if( true ){
self.itemsLimit.set(self.itemsLimit.get()+self.ITEMS_INCREMENT);
console.log(self.itemsLimit.get()); // set values are fine
}
});
});
Template.home.helpers({
testHelper: function(){
console.log(Template.instance().itemsLimit.get()); // console returns 2 and 4 only. no more update :(
return true;
}
});
Anything wrong in handling of data or usage? How to make helpers are workable?
Well well well, I don't see where are you going to change the value of reactive variable. It gets changed only ones, when first computation runs in your tracker. So only ones you see the update. The idea of using ReactiveVar is that when you change it, it gets changed inside helper or inside autorun.
Briefly, what you can do to test it is:
Template.home.onRendered(function () {
var self = this;
Meteor.setInterval(function(){
self.itemsLimit.set(self.itemsLimit.get()+self.ITEMS_INCREMENT);
}, 500);
});

Meteor run a function when a mongo collection gets updated

I am trying to do a simple prototype using Meteor (I am very new to Meteor).
I have the following in an isClient block
Template.imageList.helpers({
images: function() {
return Images.find({});
},
}
);
Then for quick demo purposes I am inserting data with meteor mongo and the following
db.images.insert({ imgSrc: "http://mysite/img1.png", createdAt: new Date() })
This works and I can see the change reflected on the ui but I need to also run a client side javascript function when this occurs. I have been trying things like pub/sub and Tracker but can't get anything to work.
Any guidance would be great.
Using meteor-collections-hooks its the more easy way to accomplish this.
meteor add matb33:collection-hooks
For example.
Images = new Mongo.Collection('Images')
example = function(){
console.log("updated")
}
if (Meteor.isClient) {
Images.before.update(function(userId, doc, fieldNames, modifier, options){
example();
})
}
the example() function will run each time the Images collection get updated.
Use observeChanges :
Images.find().observeChanges({
added: function (id, fields) {
runFunction();
},
changed: function (id, fields) {
runFunction();
},
removed: function (id) {
runFunction();
}
});
See here for more: http://docs.meteor.com/#/full/observe_changes
Run function on the client's template helper, like:
Template.imageList.helpers({
images: function() {
imgs = Images.find({});
yourFunction();
return images;
}
});
Or use Tracker.autorun wrapper:
Tracker.autorun(
Images.find({});
yourFunction();
)

Meteor Iron Router Run function when collection changes

Im new to Meteor and Im trying to figure out how to run a function after a collection change.
I have a route(iron router) that subscribes to a collection with waitOn. Which just waits for the subscrition to be ready before rendering which is what I want.
waitOn: function () {
return Meteor.subscribe('collection', this.params._id);
},
Any changes to the collection will be updated on all the clients and rendered automatically.
How would I run a function once the collection has changed?
You can use the onData hook, provided that you're returning that data using the data helper. E.g this is what a route may look like
this.route('routename',
path : '/abc',
waitOn: function () {
return Meteor.subscribe('collection', this.params._id);
},
data: function() {
return Collection.findOne({_id: this.params.id});
}
onData: function() {
//Do something when the data found by the above changes
}
});

How to properly replace this.stop() with pause() on Iron Router blaze integration

When I upgrade Iron Router to blaze integration branch, I began receiving this warning:
"You called this.stop() inside a hook or your action function but you should use pause() now instead"
Chrome console --> iron-router.js:2104 --> client/route_controller.js:193 from package
The code is on client:
Router.before(mustBeSignedIn, {except: ['userSignin', 'userSignup', 'home']});
var mustBeSignedIn = function () {
if (!Meteor.user()) {
// render the home template
this.redirect('home');
// stop the rest of the before hooks and the action function
this.stop();
return false;
}
return true;
}
I tried replacing this.stop() with: pause(), Router.pause() and this.pause() but still does not work. Also I haven't found pause function on iron-router package.
How do I properly replace this.stop() with pause()?
Thanks
From what I can tell the pause function is the first parameter your before hook is getting called with. Not in the docs anywhere, but that's what I gathered from the code and it seems to work.
Here's what I use:
var subscribeAllPlanItems = function (pause) {
var planId = this.params._id;
this.subscribe('revenues', planId).wait();
this.subscribe('expenses', planId).wait();
};
var waitForSubscriptions = function (pause) {
if (this.ready()) { //all the subs have come in
//NProgress.done();
setPlan(this.params._id);
} else { //all subscriptions aren't yet ready, keep waiting
//NProgress.start();
pause();
}
};
Router.map(function () {
this.route('calendar', {
path: '/calendar/:_id',
template: 'calendar',
before: [
subscribeAllPlanItems,
waitForSubscriptions
],
});
//Other routes omitted
});
var requireLogin = function (pause) {
if (Meteor.loggingIn()) { //still logging in
pause();
}
if (!Meteor.user()) { //not logged in
this.render('signIn');
pause();
} else { //logged in, life is good
console.log("requireLogin: logged in");
}
};
//This enforces login for all pages except the below ones.
Router.before(requireLogin, {
except: ['landing', 'signUp', 'signIn', 'forgotPassword', 'resetPassword']
});
I opened an issue on Github about this. Here's the response I got:
Oops I may have not changed the redirect method yet. Just use Router.go as it will work fine now. I will change over this.redirect sometime next week or a PR is welcome. Controllers are now automatically stopped if you change routes in a hook. You can pause the current run by calling the pause method which is passed as a parameter to your hooks and action functions.

Resources