[SOLVED] A problem with geolocation

Hey guys, right now I’m working on an app that relies heavily on user’s geolocation. At this moment I only need to get an user’s address through this user’s latitude and longitude. To do this I use two packages: mdg:geolocation (to get latitude and longitude) and meteor-google-reverse-geocode (to transfrom latitude and longitude into an address).
Right now I have the following code:

import React, { Component, PropTypes } from 'react';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Geolocation } from 'meteor/mdg:geolocation';
import { reverseGeocode } from 'meteor/jaymc:google-reverse-geocode';

export default class Profile extends Component {
    setLocation() {
        var latLng = Geolocation.latLng();
        var lat = latLng.lat;
        var lng = latLng.lng;
        reverseGeocode.getSecureLocation(lat, lng, function(location) {
            Meteor.users.update(Meteor.userId(), {
                $set: {"profile.location": reverseGeocode.getAddrStr()}
            });
        });
    }
    render() {
        return (
            <div className="container">
                <div className="row">
                    <div className="col s4">
                        <User />
                    </div>
                    <button onClick={this.setLocation.bind(this)}>Set location</button>
            	</div>
	</div>
        )
    }
}

I have a User component which displays user’s location among other parameters but at first it should be getting this location param from registration and the log in (I’ll implement sessions later), so I created a button that does the trick but only when I click it twice. With first click it doesn’t get any info rather showing me an error in console but when I hit it second time it somehow works as I want, i.e getting the right address and then displaying it in my User component. Okay, it can grab the data but only if I click it twice which is not acceptable because I want to grab this data after registration or logging in, i.e with very first click, not the second one, but I still don’t know how to do it. Any help or thoughts would be appreciated. Thanks for your time you dedicated to described problem!

UPD

After some research, I found that Geolocation function isn’t reactive and it could take some time to load data, so I used ReactiveVar to make it reactive and Tracker to manually stop calculation when it’s completed. Now my code looks like this:

setLocation() {
    var latLng = new ReactiveVar();
    Tracker.autorun(function(computation) {
        latLng.set(Geolocation.latLng());
        if (latLng.get()) {
            computation.stop();
            console.log(latLng);
            var lat = latLng.lat;
            var lng = latLng.lng;
            reverseGeocode.getSecureLocation(lat, lng, function(location) {
                Meteor.users.update(Meteor.userId(), {
                    $set: {"profile.location": reverseGeocode.getAddrStr()}
                });
            });
        }
    })
}

It computes lan and lng properties with first click but here comes another error Uncaught TypeError: Cannot read property 'formatted_address' of undefined in google-reverse-geocode.js file.

Okay guys, I solved this problem. I took a look in ReactiveVar output and realized what was my mistake. See, the output contains and object curValue where lan and lng properties are stored, so to extract these properties I just had to call them explicitly like latLng.curValue.lat. Here’s fixed function that works the way I described in my first post:

setLocation() {
    var latLng = new ReactiveVar();
    Tracker.autorun(function(computation) {
        latLng.set(Geolocation.latLng());
        if (latLng.get()) {
            computation.stop();
            console.log(latLng);
            var lat = latLng.curValue.lat;
            var lng = latLng.curValue.lng;
            reverseGeocode.getSecureLocation(lat, lng, function(location) {
                Meteor.users.update(Meteor.userId(), {
                    $set: {"profile.location": reverseGeocode.getAddrStr()}
                });
            });
        }
    })
}

Hope it helps someone!

2 Likes

Hi,
I know it haas been a while since this question was answered. I have a follow up on this.
How do you implement the callback on reverseGeocode.getSecureLocation(lat, lng, function(location) {