...

Great news ! (02/2014)

Business wants to fully rebuild the webapps

AngularJs is becoming more and more popular, we try it, it looks awesome!

What do we have to do?

...exactly

betclic sport .fr

betclic casino .com

betclic turf .fr

expekt casino .com

expekt sport .com

betclic sport .com

betclic sport .it

montecarlo casino .com

...more than 15 webapps

4 universes

3 brands

Ios & Droid apps using webviews

100 000 single users per month, 3 000 000 bets per month

... must confess not so good with Javascript

Betclic is betting on AngularJs

AngularJs in a .Net world

by Hugo Mercier -- @HugoM321
& Antoine Sauvinet -- @oinant

Target

Multi-tenant: same package per universe for all brands

No Duplicated code

Unit tests & Integration tests

The business wants webapps with same functionnalies and look and feel as the native apps

Team: Time to learn

Mob programming

One Team, one screen, one keyboard

Fix a goal: a real user story

Prepare a detailed dojo and play it in front of the team

The team replays it and switches keyboard every 10min

The code is ours

Write our own coding conventions

Let's talk

architecture

the WebApi

full C#

not a lot of code to write: just an optimized presentation layer

shared core used on web front

What's the job of the MVC webapp?

It's just one HomeController with one action

not only serve our angular app but also injects dynamic javascript

analyzes the incoming request:

https://m.betclic.com/sport/

injects token & context in a constant service

								window.contextToken = "eyJ0eXA..";
angular.module('global').constant('appContext', {
	"channelId":"BetclicMobile",
	"applicationId":"BetclicCom",
	"legislation":"Com",
	"universe":"Sports",
	...});
})();
								
							

bootstraps constants from config file and database


							angular.module("sport.core").constant("sportInitialData", {
	sportWebApiUrl:"https://webapi/url",
	iconsSportUrl:"https://cdn/url",
	...
});						

chooses the corresponding bundle

https://m.betclic.com/sport/
script src="/sport/build/mon_bundle_betclic_com.js?v=15.010"
						Or
						
https://m.betclic.fr/sport/
script src="/sport/build/mon_bundle_betclic_fr.js?v=15.010"

It means we need to build one bundle/app per brand!

Thanks to our gulp build chain

Easy to override

for example this is my default directive: mySuperDirective.js
and this is the custom directive for .fr: fr.mySuperDirective.js

In gulp config file, we describe our different applications:

								applications: [
{
    name: 'BetclicCom',
    code: 'com'
},
{
    name: 'BetclicFr',
    code: 'fr'
},
{
    name: 'ExpektCom',
    code: 'expektCom'
}]
								
							

so for each applications:

								config.applications.forEach(function (application) {
    var taskName = application.code + '_scripts';
    gulp.task(taskName, function () {
        
        return gulp.src(tools.GetFilesFilteredByApplicationCode(..))

            .pipe($.if(configBuild.minify, $.uglify()))

            .pipe($.concat('app_' + application.code + '.js'))

            .pipe(gulp.dest(config.paths.build));

    });
    scriptsTasks.push(taskName);
});
							

method "GetFilesFilteredByApplicationCode" will do the magic

so in the build folder, we have:

app_com.js

app_fr.js

app_expektCom.js


same for templates!

Global

Global

Common infrastructure:

  • Shared directives
  • Client Auth management

Global

Transversal features

  • Login
  • Registration
  • Payment
  • Marketing
  • Customer account

Global

Universe apps are loosely coupled to common feature,

but still tightly coupled to the Infrastructure changes!

Global

Our approach is very pragmatic

As many entreprise-grade applications, we made some trade-off regarding the purity of our application

For instance, the payment domain is really complex and business-critical

Global - Payments

The decision was to integrate our existing web-cashier directly int the web-app, through an iframe integration

To do so, we simply added some mobile-designed razor views,

update the view-engine,

							DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("mobile")
{
     ContextCondition = IsFromMobileWebApp())
});
							
						

cutsomize a bit our SSO and...

Translations

Betclic is present in 21 languages. We obvioulsy rely on a CMS, built a long-time ago...

Our webapps have to support different languages, and for performance purpose, we couldn't afford to preload all the needed ressources

We built our client side language management over the awesome angular-translate module, wich handles batching ressources fecthing, local-storage persistance

Each universe is responsible for registering its own languageProvider:

							
angular.module('sport.helpers')
       .factory('translationProvider', translationProvider);
translationProvider.$inject = ['translationSvc']; // Restangular ressource
function translationProvider(translationSvc) {
    return {  
    	universe: 'sport', 
    	load: function () { return translationSvc.getTranslations(); } 
    }
} 
							
						

Then the global module loads and puts everything in cache:

							
function checkGlobal(languageCode) {
    return $http.get(envContext.globalApi + 'translation'); // global resource
}

function checkUniverse(languageCode) {
    var provider = $injector.get('translationProvider');
    return provider.load();
}					
							
						

Working with Visual Studio

sidewaffle

http://sidewaffle.com/

Templates for Visual Studio by John Papa

JSON-Intellisense

https://github.com/madskristensen/JSON-Intellisense

NPM and Bower package Intellisense directly Visual Studio JSON editor

Task Runner Explorer

https://visualstudiogallery.msdn.microsoft.com/8e1b4368-4afb-467a-bc13-9650572db708

A task runner for Grunt and Gulp directly within Visual Studio

IntelliSense for AngularJS in Visual Studio

https://github.com/jmbledsoe/angularjs-visualstudio-intellisense/

Intellisense in JavaScript files for injected AngularJS components in Visual Studio.

Let's go to prod!

@Indus team: "Can you please install node.js on TFS build server"

How to use gulp in Microsoft build?


Custom nuget package with node,npm and git standalone version

https://www.nuget.org/packages/Betclic.BuildTools.Node/1.0.0

Post build Event: npm install, bower install, gulp tasks

why not ?

First weeks: all good :)

we have the look and feel of native app

But too much limitations

« It’s for app, not webapp »: Ionic team

Browser compatibility (IE …)

Integration team unhappy

So if you are a front .net dev

don't be afraid to use AngularJs !

THANKS!