feedback using angularjs + typescript at serenytics

Post on 12-Aug-2015

54 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

FEEDBACKANGULARJS + TYPESCRIPT AT SERENYTICS

TypeScript meetup #2 - Paris2015-06-10

Adrien Chauve CTO

@adrienchauve@Serenytics

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

CONTENTS1. 2. 3. 4.

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

1. WHAT WE DO: DASHBOARDS AND WIDGETS

1. WHAT WE DO: DASHBOARDS AND WIDGETS

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

13 $1,034 $339

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!

2. WHY MOVING TO TYPESCRIPT?

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)

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

3. ANGULAR + TYPESCRIPT: HOWTO?

3. ANGULAR + TYPESCRIPT: THE BASICSControllerServiceDirective

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' })

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;})();

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; }); }}

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);

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();});

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, ...)

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

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)

4. THE GOOD, THE BAD AND THE UGLY

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

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)

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() {}

constructor() {}

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

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

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)

REFERENCES Course

@ Pluralsight by @Foxandxss

by @john_papa

Using TypeScript for Large AngularJS Applications

Why Will Angular 2 Rock?Angular style guideTypeScript Roadmap

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 adrien.chauve@serenytics.com

top related