A Working Nomad Now

Somewhere between the Thakek Loop in Laos and Danang Bay in Vietnam… my friend forwarded me a job listing – and the email traveled in minutes all the way from Princeton, NJ to my phone in Four Thousand Islands in the South of Laos.

One really shaky Skype call later and after sending my resume over email – I stopped being a freelancer and I entered the ranks of the employed. I’ve been grinding the last two months in Bangkok, working with an amazing product and marketing team. Last month I visited Bagan in Myanmar, and last week we set up a project in Kirtipur, Nepal.

I’ve been so blessed – but also have struggled immensely over the last few months. It’s easy to lose myself in the distraction of technology or endless tasks. It’s tough to simply surrender and accept the unpleasant things in life. To let the past go. To focus on the present and the future.

I’ve been deeply influenced by Buddhist philosophy – from Dialectical Behavioral Therapy, to the teachings of Eckhart Tolle, to wanting to go to Vipasana – and attending a class at the Rangjung Yeshe Institute.

Sometimes  I wonder if it’s too late though. Moments like today when my heart spasmed for 20 seconds and I started to feel dizzy. In that moment I thought my heart wouldn’t start beating again, and I was excited at the thought that it might not. I know a candle that burns brightly, burns out faster.

I’ve done a lot, traveled a lot, experienced a lot. I feel like an old woman inside. And biologically, stress makes you age more – the telomeres divide and shorten faster. I know that my stress levels are regularly 10x what is healthy.. but it’s the life I choose.

Mom, Dad, Sonia – I love you. This is in case my heart actually does stop beating tonight. And everyone else, I love you too! It’s been a great ride in this collective boat of humanity. Each day is a blessing, full of both pain and pleasure. Full of samsara. I am sorry to the people who I’ve hurt.

(Alex McGlothlin, I was really mean to you and you didn’t deserve it – and I’m sorry.)

(Jeff Liu, I was also inconsiderate and selfish and you were a great person and great friend. I really love you and hope all is well)

❤ the world, the universe, humanity – and am ready for whatever adventure comes next. Whether it’s another day in this life, or something else beyond. 🙂

getmii.com getmii getme get me doyougetmii goyougetme need kornukopiarala

Understanding Reactivity in Meteor using Iron Router and Google Maps

Often Meteor JS can feel like magic.

I’ve been working with Meteor for a few weeks now, and just now grasped the full splendor of Meteor Reactivity. If you are new to Meteor, this is a short read that will give you an “aha!” moment.

Here’s the project I’m working on, it is very simple.

Before the reactive way, was the non-reactive way. It involved about a hundred lines of code dedicated to controlling and managing timer intervals for certain variables whose load times were variable. Those days are gone.

The Reactive Way

In my project/lib/environment.js file I define routes for http://www.coffee-and-wifi.in/ and http://www.coffee-and-wifi.in/bangkok

The hooks (the functions) are reactive – which is awesome because it means that anytime one of the Session variables changes, all functions that use those specific Session variables will re-run.

Since I’m writing this website through a VPN in China, the load speeds for each one of the code blocks below is really variable. The problem here, is that in order for Google Maps to render a map, it needs coordinates for the center of the map (Block #3) . In order to get coordinates for the center of the map, I need to get information from Iron Router about which map to load (Block #2). If I need to load the current location map, I need the current location (Block #1).

Code Block #1 – Navigator

Meteor.startup(function() {

 // get current position
 if (navigator.geolocation) {
   navigator.geolocation.getCurrentPosition(getPosition);
 } else {
   alert("Geolocation is not supported by this browser.");
 }

});

Code Block #2 – Iron Router

Router.route('/', function () {
 Session.set('latitude_center', Session.get('latitude_current'));
 Session.set('longitude_center', Session.get('longitude_current'));
});

Router.route('/bangkok', function (){
 Session.set('latitude_center',13.741943);
 Session.set('longitude_center',100.548653);
});

Code Block #3 – Google Maps

This block involves David Burle’s dburles:google-maps package, which really neatly wraps up the Google Maps API for easy Meteor accessibility.

In the app-maps/client/maps-client.js (I chose to structure my files into subdirectories) I have the helper functions for the template called “map”. Helper functions are by default reactive computations which means that anytime a reactive piece of data (like a Session variable) inside the function changes, the function is re-run. So take a second to look at the code.

Template.map.helpers({
 // This is a helper function, so it is a 'reactive computation'
 // Any time a Session variable inside it changes, the function surrounding it will run again

 exampleMapOptions: function() {

  if(GoogleMaps.loaded()){

  // Map initialization options
   return {
    center: new google.maps.LatLng(Session.get('latitude_center'), Session.get('longitude_center')),
    zoom: Session.get('zoom'),
    mapTypeControl: true,
    navigationControl: true,
    scrollwheel: false
   };
  }
 }
});

The return function causes the Google Map to render. And since the helper function is a reactive computation, whenever the Session variable for ‘latitude_center’ and ‘longitude_center’ change, the center of the map will move accordingly.

Summary

In Block #2 the Session variable for ‘latitude_center’ (center of the map) is set to equal ‘latitude_current’ (current location). Most of the time, when this code is first called, the current location is not yet known. So initially ‘latitude_center’ is undefined. If it stays undefined, no map will load.

In Block #1 the Session variable for ‘latitude_current’ is set. Sometimes it takes the navigator a while to get running. Sometimes Block #3 runs before Block #2 and the map renders as a gray because the values for the center are undefined.

Finally, in Block #3 the map is rendered according to Session variables for the center of the map. If either Block #1 or Block #2 haven’t finished running, the map will be gray. If you pay close attention, you might notice it load gray before quickly changing to a visible map.

The nifty thing, is that it doesn’t matter which order these blocks load. Because they are all linked together with reactive Session variables, each block gets “notified” when it’s time to update.

More Practice

For more practice, check out David Burles’ How to create a reactive Google map in Meteor.

getmii.com getmii getme get me doyougetmii goyougetme need kornukopiarala