feedback using angularjs + typescript at serenytics

28
FEEDBACK ANGULARJS + TYPESCRIPT AT SERENYTICS TypeScript meetup #2 - Paris 2015-06-10 Adrien Chauve CTO @adrienchauve @Serenytics

Upload: adrien-chauve

Post on 12-Aug-2015

50 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Feedback using Angularjs +  Typescript at Serenytics

FEEDBACKANGULARJS + TYPESCRIPT AT SERENYTICS

TypeScript meetup #2 - Paris2015-06-10

Adrien Chauve CTO

@adrienchauve@Serenytics

Page 2: Feedback using Angularjs +  Typescript at Serenytics

DISCLAIMERI'm not a TypeScript expert, nor an AngularJS expert!But it's better if you know some to follow this talk ;-)

Page 3: Feedback using Angularjs +  Typescript at Serenytics

CONTENTS1. 2. 3. 4.

What we do: Dashboards and WidgetsWhy moving to TypeScript?Angular + TypeScript: HowTo?The Good, the Bad and the Ugly

Page 4: Feedback using Angularjs +  Typescript at Serenytics

1. WHAT WE DO: DASHBOARDS AND WIDGETS

Page 5: Feedback using Angularjs +  Typescript at Serenytics

1. WHAT WE DO: DASHBOARDS AND WIDGETS

Year -- All -- Product -- All -- Country -- All --

13 $1,034 $339

Page 6: Feedback using Angularjs +  Typescript at Serenytics

1. WHAT WE DO: DASHBOARDS AND WIDGETSInitial question:

we use AngularJS with lots of different widgetshow to reuse as much code as possible?while still being able to tune each widget appearance

Solutions:

Service: not enough (factorize logic but not UI interactions)Single generic directive: single template problemDirective composition: a generic base directive plus severalsmall directives to adapt the template and behaviorTypeScript to the rescue, and much much more!

Page 7: Feedback using Angularjs +  Typescript at Serenytics

2. WHY MOVING TO TYPESCRIPT?

Page 8: Feedback using Angularjs +  Typescript at Serenytics

2. WHY MOVING TO TYPESCRIPT? (1/2)Potential good solution to factorize our code (more on thatlater)All the goodness of ES6 (classes, fat arrow, templatestrings, soon async/await, ...), plus:statically typed

automatic feedback while developing (think gulp/gruntwatch)interfaces! description of complex types (e.g. widgetdata model) available in a single place and not spreadaround the code (Angular is really persmissive formodels)

Page 9: Feedback using Angularjs +  Typescript at Serenytics

2. WHY MOVING TO TYPESCRIPT? (2/2)It's just a Javascript superset, so the migration can beincremental and smooth, no need to rewrite the app fromscratchreally easy integration with Angular (even if a little scary atfirst)forces to use classes, and then better organize the code(again Angular is really permissive)Angular2 is written in TypeScript: Google + Microsoft arenow supporting it

Page 10: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: HOWTO?

Page 11: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: THE BASICSControllerServiceDirective

Page 12: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: THE BASICS - CONTROLLERSUsing ControllerAs syntax, a controller is just a Class

angular .module('my-lib') .controller('LoginController', LoginController);

$stateProvider .state('login', { url: '/login', templateUrl: 'mylib/auth/login.template.html', controller: 'LoginController', controllerAs: 'vm' })

Page 13: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: THE BASICS - CONTROLLERSExample in ES5:

var LoginController = (function () { function LoginController(loginService, $state) { this.loginService = loginService; this.$state = $state; this.invalidCredentials = false;

if (loginService.isLogged) { $state.transitionTo('home'); } } LoginController.prototype.login = function () { var _this = this; this.invalidCredentials = false; this.loginService.loginWithCrendentials(this.email, this.password) .catch(function () { _this.invalidCredentials = true; }); }; return LoginController;})();

Page 14: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: THE BASICS - CONTROLLERSExample in TypeScript: lots of goodness in it

class LoginController {

invalidCredentials = false; email: string; password: string;

constructor(private loginService: ILoginService, private $state: angular.ui.IStateService) { if (loginMgr2.isLogged) { $state.transitionTo('home'); } }

login () { this.invalidCredentials = false; this.loginService.loginWithCrendentials(this.email, this.password) .catch(() => { this.invalidCredentials = true; }); }}

Page 15: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: THE BASICS - SERVICESJust like Controllers:

class LoginService {

constructor(private Restangular: restangular.IService) { }

loginWithCrendentials (email: string, password: string) { return this.Restangular.one('api/token') .then((apiData) => { // ... save token // ... transition to 'home' state }); } }

angular .module('my-lib') .service(loginService, LoginService);

Page 16: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: THE BASICS - DIRECTIVESinterface IWidgetDirectiveScope extends ng.IScope { widgetModel: IWidgetModel;}

class WidgetDirective { scope = { widgetModel: '=', }; restrict = 'E'; replace = true; controllerAs = 'vm'

templateUrl = 'components/widgets/widget.directive.html'; controller = WidgetController;

link = (scope: IWidgetDirectiveScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, controller: WidgetController) => { // ... }}

angular.module('my-lib').directive('my-widget', () => { return new WidgetDirective();});

Page 17: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: EVEN MORE!ok Angular + TypeScript is cool, but what about code reuse

and our initial question?

Lots of common behavior between

table widget / value widget (= single cell table)all chart widgets (pie chart, bar chart, curve chart, ...)

Page 18: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: REUSE CODE!Different ways:

keep the same controller, adapt the template, 2 directivesfor the same price!inherit base controller to inherit basic behavior exposed tothe view (think Mixins when available)

refresh state (reload data from API)error handlingglobal data filteringdata export

implement models (e.g. Widgets) as classes completelyoutside of Angular's world

Page 19: Feedback using Angularjs +  Typescript at Serenytics

3. ANGULAR + TYPESCRIPT: OUR SOLUTION FOR CODE REUSEkeep directives small and simple, and have several ifneeded

each customized with its own templatewith possibly one base directive to factorize $scopefeatures and simple properties (replace, ControllerAs, ...)

one base controller and several inherited controllers asneededpure TypeScript Widget classes without any Angulardependency (model/business logic)

Page 20: Feedback using Angularjs +  Typescript at Serenytics

4. THE GOOD, THE BAD AND THE UGLY

Page 21: Feedback using Angularjs +  Typescript at Serenytics

4. ANGULAR + TYPESCRIPT: THE GOOD PARTSeasy integration with Angular, especially with ControllerAssince 1.2even encourage to use best practises for Angular 2(ControllerAs => Components)incremental migration (superset + gradual typing with any)type infos, type inference and all the good that comes withitInterfaces: all the model in one place!Good debugging experience using source maps withChrome

Page 22: Feedback using Angularjs +  Typescript at Serenytics

4. ANGULAR + TYPESCRIPT: THE BAD PARTS (1/2)using 3rd party libraries (missing or outdated typeddefinitions): but not such a great problemdev environment a little more complex (gulp, tsc, tslint,tsd): actually not so much paina little more work sometimes (adding types, directivesmore verbose)

Page 23: Feedback using Angularjs +  Typescript at Serenytics

4. ANGULAR + TYPESCRIPT: THE BAD PARTS (2/2)Dealing with class hierarchies: compromise between testability and verbosity

class BaseWidgetController { private _data: IData;

constructor(private globalFilterService: GlobalFilterService /* other dependencies */)

filterData () { return this.globalFilterService.applyFilters(this._data); }}

class TableWidgetController extends BaseWidgetController { constructor(private globalFilterService: GlobalFilterService /* other dependencies */) super(globalFilterService, ....); }}

/* less verbose alternative - dangerous */class GlobalFilterService { /* WARNING: bypass Angular DI and make testing more complex */ static instance() { angular.element(document.body).injector().get('globalFilterService' } applyFilters(...) {...}}

class BaseWidgetController { private _data: IData; constructor() {}

Page 24: Feedback using Angularjs +  Typescript at Serenytics

constructor() {}

filterData () { return GlobalFilterService.instance().applyFilters(this}

Page 25: Feedback using Angularjs +  Typescript at Serenytics

4. ANGULAR + TYPESCRIPT: UGLY PARTS?Not really... or maybe

when coding e2e tests with Protractor + TypeScript:incompatible Promises types

// selenimum-webdriver type declarationinterface IThenable<T> { then<R>(opt_callback?: (value: T) => Promise<R>, opt_errback?: (error: then<R>(opt_callback?: (value: T) => R, opt_errback?: (error: any) => any): Promise<R>;}

// vs. ES6 type declarationinterface Thenable<R> { then<U>(onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: then<U>(onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error:}

Good luck if you use nodejs withQ.denodeify or Bluebird.promisify

Page 26: Feedback using Angularjs +  Typescript at Serenytics

TOWARDS ANGULAR 2.0: ANGULAR IN TYPESCRIPTIf you:

have a growing project in Angular 1.Xwant to invest on it for the next couple of years

Do you a favor, go for TypeScript!Congrats! you'll be half way through the migration to

Angular2!

Angular 2: everything becomes a TypeScript class withannotations (Component, Directive)

Page 27: Feedback using Angularjs +  Typescript at Serenytics

REFERENCES Course

@ Pluralsight by @Foxandxss

by @john_papa

Using TypeScript for Large AngularJS Applications

Why Will Angular 2 Rock?Angular style guideTypeScript Roadmap

Page 28: Feedback using Angularjs +  Typescript at Serenytics

QUESTIONS?Want to work with us at Serenytics?

Interested by Analytics, BI and Startups?Passionate about Angular and TypeScript? Love Python?Come and see me, we're looking for an amazing dev /startuper!Or contact me at [email protected]