Using ts-serializer to serialize and deserialize JSON Objects

Serializing?

Serialization is the process of converting complex objects into a data format that can be easily stored or sent across a network connection. In JavaScript, serialization and deserialization of objects can be achieved by using JSON.stringify() and JSON.parse().

Example

 // Let's say you have a simple json response from your server.
 var jsonResponse = "{firstName:\"John\", lastName:\"Doe\"}";

 // If you want to deserialize this object, you can use JSON.parse().
 var jsonParsed = JSON.parse(jsonResponse);

 // An object with the correct properties will be returned
 console.log(jsonParsed.firstName); // Prints 'John'
 console.log(jsonParsed.lastName); // Prints 'Doe'

 // If you want to serialize the object back into a string represantation, you can use JSON.stringify()
 var serializedJson = JSON.stringify(parsedJson);
 console.log(serializedJson); // Prints '{firstName:"John", lastName:"Doe"}'

The Problem?

Things start to get complicated when you are using TypeScript or ES6 and the response from the server doesn’t really match your client data structure. In this case you have an extra step of copying the properties from the parsed json response into your custom model object. When you want to send the data back to the server you have to copy the properties again into their original format.

Example

 // The response from the server
 let response:string = "{first_name:\"John\", last_name:\"Doe\"}";

 // Your model class
 class UserProfile {
     firstName:string;
     lastName:string;
 }

 let jsonParsed = JSON.parse(response);

 var userProfile = new UserProfile();
 userProfile.firstName = jsonParsed.first_name;
 userProfile.lastName = jsonParsed.last_name;

 // When you want to send the data back to the server you have to do the same things as above but in reverse.
 let dataToSend = {
     first_name: userProfile.firstName,
     last_name: userProfile.lastName
 };

 let dataAsString = JSON.stringify(dataToSend);

 console.log(dataAsString); // Prints {first_name:"John", last_name:"Doe"}

 // It's easy to see that when you have lots of properties this gets very messy, very quickly

Solution? Introducing TS Serializer

Some time ago I have started using TypeScript for most of my projects. One of those projects had a very different data structure between the server and the client. After getting very frustated with writing serialization and deserialization methods for my data models, I came up with the ideea of ts-serializer. ts-serializer is a collection of typescript decorators and helper classes that allows the developer to easily serialize and deserialize complex objects to and from JSON objects.

Installation

Using NPM

npm install --save ts-serializer

Build from Git

git clone https://github.com/dpopescu/ts-serializer.git
cd ts-serializer
npm install
npm run build

The library will be in the dist folder

Usage

You start by importing the library decorators and the Serializable abstract class

 import {Serialize, SerializeProperty, Serializable} from 'ts-serializer';

In order to mark a class as serializable, you need to use the Serialize decorator and extend the abstract Serializable class.

 @Serialize({})
 class Profile extends Serializable {
 }

The Serialize decorator implements in the target class the serialize and deserialize methods required by the Serializable class.

By default, the library does not serialize class properties if are not marked for serialization. In order to declare a property as serializable you use the SerializeProperty decorator.

 @Serialize({})
 class Profile extends Serializable {
     @SerializeProperty({})
     firstName:string;
     @SerializeProperty({})
     lastName:string;
 }

After the class and the class properties are marked as serializable, you can use the serialize and deserialize methods and ts-serializer will take care of things for you.

Full Example

import {Serialize, SerializeProperty, Serializable} from 'ts-serializer';

@Serialize({})
 class User extends Serializable {
     @SerializeProperty({
        map: 'first_name'
     })
     firstName:string;
     @SerializeProperty({
        map: 'last_name'
     })
     lastName:string;
 }

@Serialize({})
 class Profile extends Serializable {
     @SerializeProperty({
        type: User
     })
     user: User;
 }

 let data = {
    user: {
        first_name: 'John',
        last_name: 'Doe'
    }
 };

 let instance:Profile = new Profile();
 instance.deserialize(data);

 console.log(instance.user.firstName); // Prints 'John'
 console.log(instance.user.lastName); // Prints 'Doe'

 console.log(instance.serialize()); // Prints {"user":{"first_name":"John", "last_name":"Doe"}}

 console.log(instance.user.serialize()); // Prints {"first_name":"John", "last_name":"Doe"}

For more information about the library check out serializer.dpopescu.me and ts-serializer Github page

AngularJS March Meetup

12768171_978210158939053_826972627716518146_o

On 14th of March I will talk about testing and documenting ES6 code using Karma, Jasmine, Istanbul, ISparta and ESdoc. The event will start at 18:30 and will take place at TechHub Bucharest.

Agenda:

  • 6:30 – 7:00 Participants arrival
  • 7:00 – 7:30 Best practices for unit testing and documenting ES6 code using Karma, Jasmine, Istanbul, ISparta and ESdoc, Daniel Popescu (Adobe Romania)
  • 7:45 – 8:15 $compile with swag, Stefan Daniel (Adswizz)
  • 8:30 – 9:00 Networking and mingle 🙂

 

Don’t forget to register here.

Dynamic loading of AngularJS components

Last week, I had the opportunity to speak about dynamic loading AngularJS modules and how can you achieve that using Webpack’s require.ensure method. The code and slides for the presentation can be found here. In the presentation I’ve only described how can you dynamically register router states. The basic ideea is to have some sort of mechanism to load application modules on demand and once they’re loaded, to register those new angular components in the main application in order to use them. Unfortunately, Angular register’s all of it’s components in the configuration phase so if you try to register a new directive or service after the configuration phase has ended, the component won’t be available for Angular to use.

Let’s take this simple example:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <!-- Include your required JS files here -->
        <!-- I'm using Webpack so everything is automatically included for me -->
        <title>Angular modular test app</title>
    </head>
<body>
    <!-- Use our application directive -->
    <app></app>
</body>
</html>
/**
* Create a test app.
*/
var app = angular.module('test', []);

/**
* Create an application directive
* I'm using the new Angular 1.5 syntax for components.
*/
app.component('app', {
    controller: function(){
        this.showNewDirective = false;

        // We only show the new directive after a button press.
        this.loadDirective = function(){
        this.showNewDirective = true;
        };
    },
    // In the directive template we are using an undefined directive "new-directive".
    template: '<button ng-click="$ctrl.loadDirective()" ng-if="!$ctrl.showNewDirective">Load new directive</button>
    ' +
    '<new-directive ng-if="$ctrl.showNewDirective">New directive not loaded</new-directive>'
});

The application looks like this:
Screen Shot 2016-02-29 at 12.25.57 PM
Once we press the button we will see the default “New directive not loaded” text because our “<new-directive>” was not yet defined.
Screen Shot 2016-02-29 at 12.25.45 PM

Now let’s modify our code to register the “<new-directive>” when we press the button.

app.component('app', {
    controller: function () {
        this.showNewDirective = false;

        // We only show the new directive after a button press.
        this.loadDirective = function () {
            // Register the new directive before showing it
            app.component('newDirective', {
                controller: function () {

                },
                template: '
<h1>New directive is here</h1>
'
                });
            this.showNewDirective = true;
        };
    },
    // In the directive template we are using an undefined directive "new-directive".
    template: '<button ng-click="$ctrl.loadDirective()" ng-if="!$ctrl.showNewDirective">Load new directive</button>
    ' +
    '<new-directive ng-if="$ctrl.showNewDirective">New directive not loaded</new-directive>'
});

Once you click the button again, you would expect that the new directive is showed because we registered it before we showed it. The actual result is this:

Screen Shot 2016-02-29 at 12.25.45 PM

This happens because once the config phase has ended, angular’s component method doesn’t use the same $compileProvider to register new components. With just this little piece of code added to the “App.js” file:

app.config(function ($compileProvider) {
    // Save the original $compileProvider to use it for dynamic registering
    app.component = function(name, object) {
        $compileProvider.component(name, object);
    return (this);
    };
});

If we press the button now we should see this:
Screen Shot 2016-02-29 at 3.44.58 PM

If we want this to work for all Angular’s components we need to change our config method into this:

app.config(function ($controllerProvider, $provide, $compileProvider, $filterProvider) {
    // Register directives handler
    app.component = function(name, object) {
        $compileProvider.component(name, object);
    return (this);
    };
    // Register controller handler
    app.controller = function( name, constructor ) {
        $controllerProvider.register( name, constructor );
    return( this );
    };
    // Register services handlers
    app.service = function( name, constructor ) {
        $provide.service( name, constructor );
    return( this );
    };
    app.factory = function( name, factory ) {
        $provide.factory( name, factory );
    return( this );
    };
    // Register filters handler
    app.filter = function( name, factory ) {
        $filterProvider.register( name, factory );
    return( this );
    };
});

Now you have a way to lazy load angular modules. Please don’t make your users download 5MB of javascript if they’re only going to use 2MB. Application modules like Admin, Settings, Profile, etc. should be loaded on demand.

Implementing a modern JS Logger

I  my last post I’ve talked about using ES decorators in your Js code. This time, I’ll try and implement a fairly simple Js Logger using class and method decorators. The idea is to have a decorator that logs something to the console every time a method is called without having to add the logging code in the method itself.

Let’s start by creating a class that will be used to test our logger.

class Person {
    constructor(name = 'Bob', age = 28){
        this._name = name;
        this._age = age;
    }

    set name(value){
        this._name = value;
    }

    setAge(value){
        this._age = value;
    }
}

Decorators are not allowed on class constructors so if we want to log something every time a new instance of Person is created, we need to decorate the class and wrap the constructor with our custom code.

Let’s create the Log decorator.

function Log(target) {

    // Create a wrapper over original constructor
    const LoggerWrapper = function () {
        // Log something every time a new instance is created
        console.log('A new instance was created');

        // Call the original constructor
        target.apply(this, arguments);
    };

    // Copy the original prototype and constructor function to the new one.
    LoggerWrapper.prototype = Object.create(target.prototype);
    LoggerWrapper.prototype.constructor = target;

    // Return the new constructor.
    return LoggerWrapper;
}

Now if we use the Log decorator on Person class we should see something in the console every time a new instance is created.

@Log
class Person {
    constructor(name = 'Bob', age = 28) {
        this._name = name;
        this._age = age;
    }

    set name(value) {
        this._name = value;
    }

    setAge(value) {
        this._age = value;
    }
}

const firstPerson = new Person(); // A new instance was created
const secondPerson = new Person(); // A new instance was created

So far, so good but this logger is not very useful if we cannot set our custom message. In order to do that, we need to modify our Log decorator to return a function instead of the target class.

function Log(message) {
    return function(target){
        // Create a wrapper over original constructor
        const LoggerWrapper = function () {
            // Log something every time a new instance is created
            console.log(message);

            // Call the original constructor
            target.apply(this, arguments);
        };

        // Copy the original prototype and constructor function to the new one.
        LoggerWrapper.prototype = Object.create(target.prototype);
        LoggerWrapper.prototype.constructor = target;

        // Return the new constructor.
        return LoggerWrapper;
    }
}

Now we can update our Person class to use the new decorator.

@Log('A new instance was created')
class Person {
    constructor(name = 'Bob', age = 28) {
        this._name = name;
        this._age = age;
    }

    set name(value) {
        this._name = value;
    }

    setAge(value) {
        this._age = value;
    }
}

const person = new Person(); // A new instance was created

Everything works exactly like before but now we can specify what message we want to log.

Now that we have this in place, we can replace our console.log with a Logger class and we should also add a logging level parameter.

We start by creating a LogLevel class.

class LogLevel {
    static DEBUG = 0;
    static INFO = 1;
    static WARN = 2;
    static ERROR = 3;
}

A Logger class.

class Logger {
    static log(message, logLevel = LogLevel.INFO) {
        // Use different console methods based on the supplied logLevel. Default is INFO.
        switch (logLevel) {
            case LogLevel.DEBUG:
                console.log(Logger.getFormattedMessage(message));
                break;
            case LogLevel.INFO:
                console.info(Logger.getFormattedMessage(message));
                break;
            case LogLevel.WARN:
                console.warn(Logger.getFormattedMessage(message));
                break;
            case LogLevel.ERROR:
                console.error(Logger.getFormattedMessage(message));
                break;
        }
    }

    // Add the time to the message
    static getFormattedMessage(message) {
        return `[${new Date().toJSON()}] - ${message}`;
    }
}

And finally we update the Log decorator to add the logging level and use our new Logger class.

function Log(message, logLevel) {
    return function(target){
        // Create a wrapper over original constructor
        const LoggerWrapper = function () {
            // Log something every time a new instance is created
            Logger.log(message, logLevel);

            // Call the original constructor
            target.apply(this, arguments);
        };

        // Copy the original prototype and constructor function to the new one.
        LoggerWrapper.prototype = Object.create(target.prototype);
        LoggerWrapper.prototype.constructor = target;

        // Return the new constructor.
        return LoggerWrapper;
    }
}

Now the output should be something like this:

[2016-02-04T16:10:10.795Z] - A new instance was created

Much better isn’t it? The only problem with using console.log to log stuff is that the browser console will tell you that the “logging” happened in Logger.js file (were the console.log is actually called) and not your class constructor. We can easily fix this by also logging the class name.

We need to update the Logger to accept a target parameter.

class Logger {
    static log(message, logLevel = LogLevel.INFO, target) {
        // Use different console methods based on the supplied logLevel. Default is INFO.
        switch (logLevel) {
            case LogLevel.DEBUG:
                console.log(Logger.getFormattedMessage(message, target));
                break;
            case LogLevel.INFO:
                console.info(Logger.getFormattedMessage(message, target));
                break;
            case LogLevel.WARN:
                console.warn(Logger.getFormattedMessage(message, target));
                break;
            case LogLevel.ERROR:
                console.error(Logger.getFormattedMessage(message, target));
                break;
        }
    }

    // Add the time to the message
    static getFormattedMessage(message, target) {
        return `[${new Date().toJSON()}][${target.name}] - ${message}`;
    }
}

and the Log decorator to send that target.

function Log(message, logLevel) {
    return function(target){
        // Create a wrapper over original constructor
        const LoggerWrapper = function () {
            // Log something every time a new instance is created
            Logger.log(message, logLevel, this.constructor);

            // Call the original constructor
            target.apply(this, arguments);
        };

        // Copy the original prototype and constructor function to the new one.
        LoggerWrapper.prototype = Object.create(target.prototype);
        LoggerWrapper.prototype.constructor = target;

        // Return the new constructor.
        return LoggerWrapper;
    }
}

After this our output will be (notice that the class name is now present in the log):

[2016-02-04T16:23:47.321Z][Person] - A new instance was created

All good for now but what if we want to use this decorator to also log something when a class method is called? In order to do this, we need to modifyour Log decorator because a method decorator needs to return the method/property descriptor and not a constructor function.

function Log(message, logLevel) {
    return function () {
        const [target, name, descriptor] = arguments;

        if (!descriptor) {
            // Create a wrapper over original constructor
            const LoggerWrapper = function () {
                // Log something every time a new instance is created
                Logger.log(message, logLevel, this.constructor);

                // Call the original constructor
                target.apply(this, arguments);
            };

            // Copy the original prototype and constructor function to the new one.
            LoggerWrapper.prototype = Object.create(target.prototype);
            LoggerWrapper.prototype.constructor = target;

            // Return the new constructor.
            return LoggerWrapper;
        }
        else {
            // If the annotated method is not a setter or getter
            if (descriptor.value) {
                // save the original method
                const method = descriptor.value;
                // and wrap it with our custom code
                descriptor.value = function (value) {
                    Logger.log(message, logLevel, target.constructor);
                    method.call(this, value);
                };
            }
            return descriptor;
        }
    }
}

Now we can use our awesome decorator on methods also.

@Log('A new instance was created')
class Person {
    constructor(name = 'Bob', age = 28) {
        this._name = name;
        this._age = age;
    }

    set name(value) {
        this._name = value;
    }

    @Log('A new age was set')
    setAge(value) {
        this._age = value;
    }
}

const person = new Person(); // [2016-02-04T16:37:14.109Z][Person] - A new instance was created
person.setAge(20); // [2016-02-04T16:37:14.110Z][Person] - A new age was set

This decorator can be extended further to automatically log the parameters passed to the constructor/method and maybe also print the method name in the logs. This can be done easily because we can use the arguments in the wrapped functions. Do you have any other improvement ideas?

P.S: Try to update the decorator to work with setters also 😛 It needs just a small change.

Practical ES7 decorators

1ifm00n-npudywtdbzag3rq

Decorators, a.k.a annotations, are a new feature coming in ES7. A decorator is basically an expression that evaluates to a function, takes the target object as a parameter and returns the modified object. Decorators are very similar to Annotations in Java, but unlike Java annotations, decorators are applied at runtime.

If you are reading this and your background is Python or Java, you may begin to imagine what decorators are good at but for the rest of you here are some nice examples:

Class decorators

// We begin by declaring the decorator.
function SimpleDecorator(targetClass){
    // We define a new static property
    targetClass.decorated = true;
    // And a new instance property;
    targetClass.prototype.alsoDecorated = true;
    return targetClass;
}

// Applying the decorator is very easy
@SimpleDecorator
class SimpleClass {

}

const instance = new SimpleClass();

console.log(SimpleClass.decorated); // -> true
console.log(instance.alsoDecorated); // -> true

Pretty easy right? A class decorator allows as to “decorate” a class with both static and instance properties or methods.The decorator takes the class in question as a parameter and returns it after it makes all the necesary modifications to it.

A decorator can also take additional parameters.

// If we want to set additional parameters, our decorator must return a function.
function SetClassId(classId){
    return function(targetClass){
        targetClass.prototype.classId = classId;
        return targetClass;
    };
}

// Pass a random value from 0 to 999 as a class id
@SetClassId(parseInt(Math.random()*999))
class SimpleClass {

}

// As you can see all instances got the same value.
// That's because the decorator is executed once on class definition.
console.log(new SimpleClass().classId); // -> 754
console.log(new SimpleClass().classId); // -> 754
console.log(new SimpleClass().classId); // -> 754

Let’s try to implement a Singleton decorator. The decorator will add a static getInstance() method that will return the same class instance every time it’s called.

// Decorator definition
function Singleton(targetClass) {
    // We will hold the instance reference in a Symbol.
    // A Symbol is a unique, immutable property of an object introduced in ES6.
    const instance = Symbol('__instance__');
    // We define the static method for retrieving the instance.
    targetClass.getInstance = function () {
        // If no instance has been created yet, we create one
        if (!targetClass[instance]) {
            targetClass[instance] = new targetClass();
        }
        // Return the saved instance.
        return targetClass[instance];
    };

    return targetClass;
}

@Singleton
class Counter {
    constructor() {
        this._count = 0;
    }

    increment() {
        this._count++;
    }

    get count() {
        return this._count;
    }
}
// Get two different references of the Counter instance.
const a = Counter.getInstance();
const b = Counter.getInstance();

console.log(a.count); // -> 0
a.increment();
// because a and b point to the same instance of Counter, b.count is also incremented.
console.log(b.count); // -> 1

Method decorators

Decorators will work on class methods also. If the decorator function took just one parameter when decorating a class, when decorating a method the parameter list changes a bit. The function will take three parameters when decorating a method.

  1. Class instance reference.
  2. Method name.
  3. Object property descriptor.

Formatting data using method decorators:

// Method decorators take three parameters
function Format(target, name, descriptor){
    // Keep a reference to the original getter
    const getter = descriptor.get;
    descriptor.get = function(){
        // Call the original getter and return the modified result.
        return getter.call(this).toUpperCase();
    };
    return descriptor;
}

class Person {
    constructor(name){
        this._name = name;
    }

    @Format
    get name(){
        return this._name;
    }
}

const dude = new Person('bob');

console.log(dude.name); // -> BOB

Validating data using method decorators:

// Method decorators take three parameters
function Format(target, name, descriptor){
    // Keep a reference to the original getter
    const getter = descriptor.get;
    descriptor.get = function(){
        // Call the original getter and return the modified result.
        return getter.call(this).toUpperCase();
    };
    return descriptor;
}

function Validate(target, name, descriptor) {
    // Keep a reference to the original setter
    const setter = descriptor.set;
    descriptor.set = function (value) {
        // If the provided value is invalid throw an error
        if (value < 0) {
            console.log('Value must be positive');
        } else {
            setter.call(this, value);
        }
    };
    return descriptor;
}

class Person {
    constructor(name) {
        this._name = name;
    }

    @Format     
    get name() {
        return this._name;
    }

    @Validate     
    set age(value) {
        this._age = value;
    }
}

const dude = new Person('bob');

console.log(dude.name); // -> BOB
dude.age = -10; // -> Value must be positive

Closing thoughts

Although no browser supports these features yet, you can still use them in your production code. For transpiling ES6 code into ES5, I recommend Babel. Combine this with Webpack and you’ll get yourself a state of the art building and developing environment.

P.S: In order to transpile decorators with Babel, you’ll need to use stage-1 preset.

P.P.S: Babel 6 doesn’t support decorators yet. You have 2 workarounds:

  1. Use Babel 5.
  2. Use Babel 6 with babel-plugin-transform-decorators-legacy plugin.

That’s it. Go build something awesome.

Factory Pattern with Angular JS and ES6

angularjs

Introduction

Remember the “Gang of Four”? For those of you who don’t know, the “Gang of Four” is a group of four programmers who wrote a famous computer programming book called Design Patterns: Elements of Reusable Object-Oriented Software. In this book they talk about finding re-usable solutions to common programming problems. The Factory Pattern is a method of creating new objects without exposing the creation logic to the outside code.

Getting started

In order to implement the Factory Pattern in Angular I am going to use Angular’s factory recipe, which creates a new service using a given function. The code will be written in ES6 for simplicity but it can be easily implemented in plain old JS.

We start by creating a base object. Let’s call it Animal.

/**
 * This will be the base class for our animals.
 */
export default class Animal {
    /**
     * Construct a new Animal object
     * @param sound - The sound this animal makes.
     */
    constructor(sound) {
        this._sound = sound;
    }

    /**
     * Logs the animal sound to the console.
     */
    talk() {
        console.log(`${this.sound} !!!`);
    }

    get sound() {
        return this._sound;
    }

    set sound(value) {
        this._sound = value;
    }
}

The next step is to create concrete implementations for our animals.

import Animal from './Animal';

/**
 * Cat extends the Animal object. It will inherit all methods and properties from it.
 */
export default class Cat extends Animal {
    /**
     * Construct a new cat object
     * @param sound - Default cat sound is &amp;quot;meow&amp;quot;
     */
    constructor(sound = &amp;quot;meow&amp;quot;) {
        super(sound);
    }
}
import Animal from './Animal';

/**
 * Duck extends the Animal object. It will inherit all methods and properties from it.
 */
export default class Duck extends Animal {
    /**
     * Construct a new cat object
     * @param sound - Default duck sound is &amp;quot;quack&amp;quot;
     */
    constructor(sound = &amp;quot;quack&amp;quot;) {
        super(sound);
    }
}

Next we need to create the AnimalFactory. This class will be in charge of creating cats or ducks based on the instructions received.

import Cat from './Cat';
import Duck from './Duck';

export default class AnimalFactory {
    /**
     * This is a static method. This means we can call this method directly on the AnimalFactory class.
     * @param animalType - What type of animal we want to create.
     * @returns {Animal} - The created animal object.
     */
    static getAnimal(animalType = &amp;quot;cat&amp;quot;) {
        switch (animalType) {
            // If animalType equals &amp;quot;cat&amp;quot; we create a new Cat object.
            case 'cat':
                return new Cat();
            // If animalType equals &amp;quot;duck&amp;quot; we create a new Duck object.
            case 'duck':
                return new Duck();
            // If animalType is not supported we throw an error.
            default:
                throw new Error(`&amp;quot;${animalType}&amp;quot; is not an animal`);
        }
    }
}

Now it’s time to test our code. We need to register AnimalFactory with angular and then we can use it in our angular code to create different animals.

import angular from 'angular';

import AnimalFactory from './AnimalFactory';

// Create an angular application.
const app = angular.module('app', []);

// Register the AnimalFactory
app.factory('AnimalFactory', ()=&amp;gt;{
    return AnimalFactory;
});

// Use the factory anywhere in your angular code.
app.run((AnimalFactory)=&amp;gt;{
    // Outputs &amp;quot;meow !!!&amp;quot; because it will create a cat object.
    AnimalFactory.getAnimal('cat').talk();
    // Outputs &amp;quot;quack !!!&amp;quot; because it will create a duck object.
    AnimalFactory.getAnimal('duck').talk();
    // Outputs &amp;quot;Uncaught Error: &amp;quot;snake&amp;quot; is not an animal&amp;quot;.
    AnimalFactory.getAnimal('snake').talk();
});

As you can see, we managed to hide the actual creation of objects from the code that is using it. This is a very simple example but imagine having very complex object creation logic with different conditions. Using the Factory Pattern we are easily able to re-use and extend this piece of code.

P.S: The sample above can be easily moved to TypeScript and used with Angular 2.

Frontend Meetup #6 – Lightning Talks

Wednesday, January 20 at 19:00, the first Frontend Meetup of 2016 will take place at TechHub Bucharest. This meetup will have a lightning talk format, where each presenter will have a maximum time of 5 minutes to present something. If you want to find new interesting things or just get to know interesting people, I highly recommend you to join the event on Facebook.

Agenda:

  • Alexandra Anghel – Google’s Mobilegeddon – State of the Mobile Web
  • Andrei Antal – Get inline
  • Maria Niță – Tips and tricks for frontend deploys
  • Costică Putnaru – React Redux form navigation
  • Ciprian Chichiriță – Voice Recognition and JavaScript
  • Radu Paraschiv – Getting it real with RTC
  • Răzvan Roșu – Atomic design
  • Sabin Tudor – Signals – A canvas experiment
  • Valentin Tureac – Centering stuff in CSS
  • Roxana Năstase – Style Guides
  • Adrian Olaru – The end of the code

12484736_10207566307369332_1090758263045160952_o