Geocode address with collection hooks on the server


Hello everyone,
I am building a webapp that requires me to geocode an address into coordinates on the server.
After the offer is inserted into the collection, I have setup a collection-hook, that calls a method (offers.geocode) that should geocode the address into coordinates and insert them then into the collection. Unfortunately I cannot get it to work. Can someone help me? :slight_smile:
My schema:

/* eslint-disable consistent-return */

import { Mongo } from "meteor/mongo";
import SimpleSchema from "simpl-schema";

const Offers = new Mongo.Collection("offers");

  insert: () => false,
  update: () => false,
  remove: () => false,

  insert: () => true,
  update: () => true,
  remove: () => true,

Offers.schema = new SimpleSchema({
  address: Object,
  // [..]
  "address.street": {
    type: String,
    label: "Street and house number",
  "": {
    type: String,
    label: "City",
  "": {
    type: Number,
    label: "Postal code",
    regEx: SimpleSchema.RegEx.ZipCode,
  "": {
    type: String,
    label: "Country",
  "": {
    type: Number,
    label: "Latitude",
    optional: true,
  "address.lon": {
    type: Number,
    label: "Longitude",
    optional: true,


export default Offers;

The collection hook:

import Offers from "../Offers";

Offers.after.insert(((userId, offer) => {
  if (! {"offers.geocode", offer, offer.address);

My method looks like this:

import Meteor from "meteor/meteor";
import NodeGeocoder from "node-geocoder";
import { Offers } from "../Offers";

export default function (offer, address) {
  const geocoder = new NodeGeocoder({
    provider: "google",
    httpAdapter: "https",
    apiKey: Meteor.settings.private.GoogleMapsGeoCodingApiKey,

  const result = geocoder.geocode(address.street + + + + address.state );
    _id: offer._id,
  }, {
    $set: {
      "": result[0].latitude,
      "offer.address.lon": result[0].longitude,
  }, {
    validate: false,


Have you checked that the method is called and returns the right value (sprinkle a few console.log()s around)?

The non-callback form of method calls on the server run “synchronously”, so should work as expected.


Why you don’t try to fetch lat/lng befor insert? Insert + method call + fetch + update > fetch + insert

And looks like you wrong defined your method…


I have defined my methods like this in another file. That makes it easier for me to write tests, so this shouldn’t be the actual problem :sweat_smile:

import { Meteor } from "meteor/meteor";
import rateLimit from "../../../modules/rate-limit";
import insert from "./insert";
import update from "./update";
import remove from "./remove";
import geocode from "./geocode";

  "offers.insert": function offersInsert(offer) { // eslint-disable-line
    return insert(offer, this.userId);
  "offers.update": function offersUpdate(offer) { // eslint-disable-line
    return update(offer);
  "offers.remove": function offersRemove(offerId) { // eslint-disable-line
    return remove(offerId);
  "offers.geocode": function offersGeocode(offer, address) { // eslint-disable-line
    return geocode(offer, address);

  methods: [
  limit: 5,
  timeRange: 1000,

Would you recommend to use the collection hooks for this (Offers.before.insert) or do you know, if Meteor provides something akin out of the box? :slight_smile:


I’m prefer do not use hooks at all. I do it manually.
Or I do it even on client side (-:


What do you insert manually? Coordinates? :slight_smile:
Client side is not an option for me…