from mvp to a product
TRANSCRIPT
FROM NOODLES TO JOHN PAPA’S
KRZYSZTOF HASIŃSKI // GETBADGES.IO
getbadges
FROM MVP TO A PRODUCT
HOW MANY OF YOU HAVE A “SIDE PROJECT”?
BEFORE THE GETBADGES NOODLES
DURING LAST 10 YEARS I HAD SEVERAL
▸ My own database (turns out databases are difficult)
▸ Movie taste comparison algorithm with torrent for downloading (worked for me ;) )
▸ Bitcoin exchange (yes, another one), even had a potential VC investor
▸ Tons of other stuff…
MOST OF THOSE I’VE NEVER FINISHED… AND
IT’S COOL
MVP MINIMUM VIABLE PRODUCT
PREPARATION
MVP PRO-TIPS
▸ Focus on the killer feature, scaffold everything else
▸ Don’t make a SPA unless you really need one
▸ Test things (with users) one at the time
OPEN A BAG OF RAMEN
“SOMETHING LIKE VISUAL STUDIO ACHIEVEMENTS”
But track things on server side…I think?
Google Chrome plugin to display notifications?
Yeah, yeah, Firefox, maybe later
Proof of concept, ready for tomorrow!
Oh shit, our data structure doesn’t fit for what JIRA/GitHub/Bitbucket/sth else sent
PUT SOUP POWDER INTO A BOWL
OK, LET’S THINK THIS THROUGH
▸ Symfony2, because that’s what I was using the rest of the day (Sorry Justyna)
▸ WebHooks are cool, let’s use WebHooks
▸ Some Angular sprinkles? Maybe later
SEPTEMBER 2014
ADDING WATER
VERSION 0.1
▸ Accepts incoming data (Redmine + GitLab?)
▸ Gives out notifications (badges) // 20 lines of JS
▸ Shows profiles
WE NEED TO DISPLAY EVENTS…LIVE-ISH
SOUP IS READY LET’S ADD NOODLES
ANGULAR TO THE RESCUE
Just one widget, I promise!Quick and dirty, our users might not like it
No SPA, ng-controller
Oh shit, add ng-cloak!
Assetic can handle this
Performance? What performance?
The battle of {{ and }}
HALF-LIFE OF A TEMPORARY SOLUTION IS FOREVER.
Me
P.O.C. != P.O.S.
2015 FIRST CUSTOMERS
NOODLES GETTING COLD
OH SHIT, OH SIHT, SO MANY BGUS, FATSER!
▸ Payments not ready (protip - implement payments early)
▸ // QUICKFIX: // TODO: // FIXME:
▸ UI + UX = Crap
GetBadges $ wc -l ng-badges.js
30 ng-badges.js
GetBadges $ wc -l ng-badges.js
50 ng-badges.js
GetBadges $ wc -l ng-badges.js
500 ng-badges.js
# 10 controllers, 2 factories,
# 3 filters, no directives
GetBadges $ wc -l ng-badges.js
5000 ng-badges.js
THAT WAS STUPID BUT SIDE-PROJECTS TURNED STARTUPS DO STUPID THINGS
…and then a tiny change required two days of work
BACK TO BASICS
SPLITTING FILES IS EASY, DECOUPLING IS HARD
▸ Angular1.x is extremely freeform
▸ We need a few rules to keep our sanity
▸ https://github.com/johnpapa/angular-styleguide
DINNER’S COOKING
MOST OF THIS STUFF IS SIMPLE
▸ One component per file
▸ Wrap everything in IIFE
▸ $http is sacred, controllers are not worthy of it
ADDING SPICES
SOME OF IT IS CONTROVERSIAL
▸ Avoid $scope, bind to controllers
▸ Keep framework stuff separate from your app (nice advice for any framework out there, you too, Rails!)
▸ LIFT Principle
EXAMPLE
controllerAs with vm [Style Y032]
/* avoid */
function CustomerController() {
this.name = {};
this.sendMessage = function() { };
}
/* recommended */
function CustomerController() {
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
Why? The this keyword is contextual and when used within a function inside a controller may change its context. Capturing the context of this avoids encountering this problem.
SOME OF IT IS NOT THE “FASTEST” WAY TO WRITE
/* recommended */
angular
.module('app.core')
.factory('dataservice', dataservice); // dataservice 1st and 2nd time
dataservice.$inject = ['$http', 'logger']; // dataservice 3rd time
function dataservice($http, logger) { // dataservice 4th time // DRYYYYYYY!!! :(
BUT IT’S MODULAR AND NOT TIED TO ANGULAR
function testyTest() {
let ds = dataservice($mockHttp, mockLogger); // POJO, testing is fun
// Oh, btw - only “$” services are bound to Angular
// Most of the stuff is now framework agnostic
} // Mocking, yay!
WHAT ABOUT GOOGLE / MGECHEV / TODDMOTTO?
▸ They are (probably) all fine, just use one
▸ For a startup pick a popular technology
▸ Focus on fast delivery to shorten the feedback cycle
COOKBOOK
IT WASN’T THAT DIFFICULT
▸ Split files according to Folder-By-Feature
▸ Extract services (thanks IntelliJ!) and directives
▸ Change views to use “controller as” syntax
▸ Change anonymous functions to named functions
▸ Remove $scope where possible
▸ Change initialisation to a function (Y080), refreshing views is now easy (and tons of code removed)
NEXT TIME ON HELL’S KITCHEN
WOULD IT BE EASIER TO WRITE USING STYLE GUIDE FROM START?
▸ Yes, but…
▸ How much time do you have for your side project?
▸ It’s 4:30 AM I just want this to be ready for a company from New Zealand/California/Whateversville, I have to go to work in 4 hours
THINGS CHANGE WHEN YOU SWITCH TO FULL TIME
THINGS CHANGE WHEN YOU START TO BUDGET YOUR TIME & MONEY
WE DID NOT REFACTOR BECAUSE THE CODE WAS SHIT*
▸ We refactor because we want to move fast
▸ …without breaking too many things
▸ Optimise for speed of development
* although it was
WHEN IN STARTUP
▸ Iterate faster than big companies
▸ Be obsessive about the contact with customers
▸ Make sure your code is flexible enough for tons of experiments
THANKS! HOW ABOUT SOME Q&A?
GetBadges passcode: IONG18