Training for Surf City Marathon 2019

“Have you ever run a marathon?”

In the words of Michael Scott I should’ve just said,

Ok…maybe that was a bit extreme but that’s the rabbit hole I found myself spiraling into at the onset of September 2018. I thought it was just another casual day in the office – copy/pasting code from Stack Overflow 😏, learning Spanish (different story…different day…) and establishing myself as The 🐐 in startup foosball.

But no, not today. This question was floating in the air that day and once two of my colleagues caught wind of my nod, my life quickly turned into this.

Contemplation

Several days later the initial trauma was gone. But everything was set in stone. This was happening. It was not part of any plan I had for the remainder of the year but oh well. It was what it was. I quickly had to find a way to add this demand to my frickin’ life. Yay 😑.

🎯 My target, Surf City Marathon on February 3, 2019.

🏆 My goal, ANYTHING under 4 hours (e.g. My Time <= 03:59:XX).

Why so specific? Well, I already rode this struggle bus back in 2008 and the final outcome was a total net time of 04:21:43.

It Will Be Fun, They Said.

I had real data. SWEET. Now was the time to use it.

Preparation

So, here I am 10+ years later with a specific goal in mind. 4 months to train. Let’s do this.

But first,

Several flutes later, I managed to write down what I needed to address this. Here’s what it looked like:

Checklist

✔️ Download Strava App.
✔️ Kick the dust off of my Nike FuelBand. Derppp…I mean download the Nike Run Club App.
✔️ Find a running community (aka peer pressure from work colleagues).
✔️ Purchase running tank tops.
✔️ Purchase running shoes (back to this later 🤔).
✔️ But more importantly, purchase short shorts.

Okay, I’ll be honest. I’m pretty much covered in DRI FIT.

NIKE, if you can hear me, CALL ME 😉.

Action

I initially committed to three days (2 short, 1 long) a week with a blend of ladders, intervals or simply just getting out there. A total of 3 to 6 miles per attempt, I knew I had to increment up the long runs (6+ mi) but starting from the ground up, this was a solid approach.

Okay, more fessing up. I tried doing all of this by just eyeballing but honestly, listening to your heart can only give you so much. Get a guided run from your running apps. This guy in particular, Coach Bennett is getting me through this sh*t.

But Sweet Baby Jesus time flies by fast. At the time of this writing, I’m less than 5 weeks away from the starting line and this is how it looks at scale:

https://www.strava.com/athletes/markreyes

I’ll plop a follow-up to this post once the race is done.

Simply put, I’m just putting as much in the bank as I possibly can. January is coming in hot and I want to ensure I do this right and for me that means socializing this madness with my colleagues, getting insight from better runners and just wiring up the laces to get after it. The marathon will come. I just need to be there.

Happy New Year to you the reader for patiently reading this mild rant (I hope you get something positive out of this) and an additional kiss to all the Russian bots that follow my blog.

Aloha 🤙🏾

 

 

 

 

Upgrade from Angular 2 to Angular 4

In an effort to create an upgrade path from an Angular 2 app to Angular 4, this is what I changed to accomplish just that.

Do note:

  • This web app predates Angular CLI and is loaded via SystemJS and not webpack.
  • This effort is an instant 60% reduction in bundled Angular library code.
  • Is backwards compatible with Angular 2.

tsconfig.json – BEFORE

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "types" : []
  },
  "exclude": [
    "node_modules"
  ]
}

tsconfig.json – AFTER

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "removeComments": true,
    "sourceMap": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es5",
    "types" : []
  },
  "exclude": [
    "node_modules/*"
  ]
}

package.json – BEFORE

{
  "dependencies": {
    "@angular/common": "2.4.6",
    "@angular/compiler": "2.4.6",
    "@angular/compiler-cli": "2.4.6",
    "@angular/core": "^2.4.6",
    "@angular/forms": "2.4.6",
    "@angular/http": "2.4.6",
    "@angular/platform-browser": "2.4.6",
    "@angular/platform-browser-dynamic": "2.4.6",
    "@angular/router": "3.0.0"
  },
  "devDependencies": {
    "concurrently": "^2.2.0",
    "lite-server": "^2.2.0",
    "typescript": "^2.0.2",
    "typings": "^1.0.4"
  }
}

package.json – AFTER

{
  "dependencies": {
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0"
  },
  "devDependencies": {
    "@types/node": "^6.0.60",
    "concurrently": "^3.1.0",
    "lite-server": "^2.3.0",
    "typescript": "^2.2.2"
  }
}

A framework for web performance

A simple yet effective spreadsheet that you or your company can use to prioritize web performance goals.

First visit factors Repeat visit factors First visit time Repeat visit time First visit goal Repeat visit goal Priority
1st byte
  • server speed
  • network speed
  • server speed
  • network speed
  • caching
1st render
  • network speed
  • critical path assets
  • network speed
  • critical path assets
  • caching
1st meaningful paint
  • network speed
  • font-loading strategy
  • image optimisation
  • network speed
  • font-loading strategy
  • image optimisation
  • caching
1st meaningful interaction
  • network speed
  • device processing power
  • JavaScript size
  • network speed
  • device processing power
  • JavaScript size
  • caching

Thanks to, Jeremy Keith

Chatbot with Microsoft Azure

In lieu of SleepScore Labs newest sleep solution, SleepScore App, our Customer Service team wanted to create a chat alternative to support this product launch.

Over the course of three furious weeks (one to vet out the needs, and two to build), I worked one-on-one with our Customer Service Manager on outlining the bare minimum of what we’d really want in this type of feature.

It’s safe to say, that you can get trapped inside of a rabbit hole fairly quickly with ideas but after easing in a bit our solution was to design an FAQ (Frequently Asked Questions) Chatbot.

We took as much existing data we could from previous customer service engagements, organized them a bit and indexed them within a Web Service called QnA Maker. I connected that dot to a Microsoft Azure Bot Service as a NodeJS Web App and published it to a channel called Live Assist.

A NodeJS chatbot powered by QnA Maker, Microsoft Azure and channel, Live Assist.

Housed entirely inside of Microsoft products, I was for the most part impressed on how straightforward it was to put all three together to build out something real customers could actually engage with. There was no additional coding on my part and getting to the finish line on time was in itself a win.

If you ever wanted to try building this out yourself here’s the bare minimum you’d need:

  • QnA Maker: which will index your questions and answers and open an end-point for your web app (chatbot) to consume.
  • Azure Bot Service: which is actually how you create the chatbot.

The optional requirement here is the channel. Building out a chatbot requires you to point your chatbot to a channel. In our case it was Live Assist because that was the requirement. But this could easily ship to other channels like Facebook, SLACK, etc.

I’ll be making a follow-up post to this for the most part as a retrospective to outline the journey and its gaps to this implementation in hopes that one day I have the opportunity to make more improvements at this first pass on building out a chatbot.

Thanks to, Microsoft Developer US for getting me started.

Differences between constructor vs ngOnInit() method

Constructor ngOnInit
Typescript feature nothing to do with Angular One of the Angular life cycle hook method
constructor is transformed to function with the same name as class created ngOnInit being added to prototype of the class created
Called by Javascript Engine Called by Angular
Constructor is automaticlly called at the time of creating object of the class Invoked by Angular when everything in the component is ready
Used for Injecting dependencies Actual business logic performed here
Not everything in component is initialized at the time of invocation Everything is ready at the time of invocation

 

Thanks to, Angular js Wiki