How I Fell in Love with JS Decorators

pablo

One of the recent addiction for our team was the usage of Decorators which are proposed in the new ES7. In this article, I am going to strip Decorators for you so that you can see the beauty of it!

If you are a coming from a Python background, the syntax and the concepts will be familiar to you. It would be relatively easy for you to pick things up. But it was not the same case for me. I have no background in any other languages. I started to code for fun. The first language I learned was javascript. Thanks to w3Schools. I heard the term Decorators back in 2015 when typescript came out. That was Greek for me at that time, so I just ignored it.

A couple of months back, I got addicted to typescript and Angular 2. I was enjoying my coding time with all new typings in my projects.

When I began Angular 2, I ignored those ‘@’ syntaxes present everywhere in angular so that I could learn the framework faster. I read about those syntaxes here and there, but I never made any efforts to learn them.

giphy (1)
(Let me just not damage my brain now)

And that one fine Monday morning came, I was curious to learn this new ES7 feature called Decorators. I started to learn it. It was worth it… Yes. I fell in love. I’ll promise you that once you learn it, it is so seductive in nature that you will try to use it everywhere you find it can be used.

As there are very fewer resources out there about JS Decorators, I decided to write down my Journey of falling in love with decorators.

giphy
(I cannot resist but fall in love)

First Things First: What the hell these Decorators are?

This is what you get when you search for Decorator Pattern.

(Source: Wikipedia)
400px-Decorator_UML_class_diagram.svg
(Don’t worry if you didn’t get the gist of it)

Even more intuitive example would be the following.

Screen Shot 2017-06-18 at 9.30.55 PM
(Source: https://sourcemaking.com/design_patterns/decorator)

WeaponAccessory is the decorator here. They add extra functionality to the BaseWeapon.

Don’t worry if you are still not clear, let me break down it for you. You will understand it further when you start creating decorators with me. Let me put it this way…

Decorators are functions that give additional super-powers to different function

giphy-downsized-large
(Decorators Give Superpower to a piece of function)

The Gist:
Just think of it as a wrapper for an object!

  • The actual object resides inside the wrapper
  • if you want to access the object you need to go through the wrapper
Eg:
A Gun -> A Gun attached with a silencer
A Box -> A Box wrapped with a wrapping paper
A JS Function -> A JS Function which does additional work than what is defined.
A JS Object -> A JS Object that has additional properties than the ones which are defined.

Decorators make it possible to annotate and modify classes and properties at design time.

Points to Note

  • Decorators are just functions

How do I use this phenomenon in JS?

Decorators are a proposed feature in ES7. ES7 is not fully documented yet. But that doesn’t mean that we can’t use them. Thanks to the compilers out there: Babel and Typescript to the Rescue.

I will be using Typescript for the examples in this article.

How do I set it up?

In your tsconfig.json , you need to set experimentalDecorators and emitDecoratorMetadata to true. and you are good to start

{
"compilerOptions": {
"module": "commonjs",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "es2015"
},
"exclude": [
"node_modules"
]
}
 (Hint: Make sure that you have the latest Typescript Version)

Shut up and watch

To make things easier, I followed a learning technique – “Shut up and code”

I am going to type in some Greek. Focus on the output, you can learn that Greek later.

  function leDecorator(target, propertyKey: string, descriptor: PropertyDescriptor): any {
    var oldValue = descriptor.value;

    descriptor.value = function() {
      console.log(`Calling "${propertyKey}" with`, arguments,target);
      let value = oldValue.apply(null, [arguments[1], arguments[0]]);

      console.log(`Function is executed`);
      return value + "; This is awesome";
    };

    return descriptor;
  }

  class JSMeetup {
    speaker = "Ruban";
    //@leDecorator
    welcome(arg1, arg2) {
      console.log(`Arguments Received are ${arg1} ${arg2}`);
      return `${arg1} ${arg2}`;
    }
  }

  const meetup = new JSMeetup();

  console.log(meetup.welcome("World", "Hello"));

Once you run the above code, you will get the following output.

Arguments Received are World Hello
World Hello

Now Uncomment the line @leDecorator and now run it…

Calling "welcome" with { '0': 'World', '1': 'Hello' } JSMeetup {}
Arguments Received are Hello World
Function is executed
Hello World; This is awesome

As you can see you just annotated a function with a decorator and now the behavior of the function is different.

Let’s Try to understand what is going here.

lets do this
 (Let’s dive deep in!)

Types of Decorators

  1. Method Decorator
  2. Property Decorators
  3. Class Decorator
  4. Parameter Decorator

Now, let’s look at each type of decorators.


Method Decorators

Method Decorators are the first type of decorators that you are going to write with me and I think you would get the essence of decorators once learn the method decorators. By using Method Decorators you would gain control over the inputs of the method and output of the method.

Decorator Signature

MethodDecorator = <T>(target: Object, key: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | Void;

Pre-Requisite

Before you write can write the first decorator, let’s learn what helps you learn the decorator.

Let’s understand the parameters of the decorator

  • target -> The object being decorated
  • key -> The name of the method being decorated.
  • descriptor -> The property descriptor of the given property. You can see the property descriptor by invoking the function Object.getOwnPropertyDescriptor()

Property Descriptors

ref: getOwnPropertyDescriptor

To get an intuitive idea about the property descriptors, Take a look at the following console code.

Screen Shot 2017-06-19 at 4.49.41 PM

var o, d;
var o = { get foo() { return 17; }, bar:17, foobar:function(){return "FooBar"} };

d = Object.getOwnPropertyDescriptor(o, 'foo');
console.log(d);
d = Object.getOwnPropertyDescriptor(o, 'bar');
console.log(d);
d = Object.getOwnPropertyDescriptor(o, 'foobar');
console.log(d);

Here we have defined, an object named o with the properties foo , bar and foobar .  Then we are logging the each properties descriptor with the method Object.getOwnPropertyDescriptor()

Let’s get a sneak peak of what value , enumerable , configurable and writable mean.

  • value – >Actual value or the function that is processed by the method/property
  • enumerable -> Whether the property should be enumerable (Whether it should be there in (for x in obj)loop)
  • configurable – >Whether the property can be configured
  • writable -> Whether the property is writable.

As you can see, all properties and methods have their own descriptors. Decorators essentially modify the descriptor to provide additional functionalities. Since you understood how the methods and properties are defined it’s time for you to go make some changes to it using decorators.

Example Method Decorator

In the following example, we are going to modify the input and the output of a method.

  function leDecorator(target, propertyKey: string, descriptor: PropertyDescriptor): any {
    var oldValue = descriptor.value;

    descriptor.value = function() {
      console.log(`Calling "${propertyKey}" with`, arguments,target);
      // Executing the original function interchanging the arguments
      let value = oldValue.apply(null, [arguments[1], arguments[0]]);
      //returning a modified value
      return value + "; This is awesome";
    };

    return descriptor;
  }

  class JSMeetup {
    speaker = "Ruban";
    //@leDecorator
    welcome(arg1, arg2) {
      console.log(`Arguments Received are ${arg1}, ${arg2}`);
      return `${arg1} ${arg2}`;
    }
  }

  const meetup = new JSMeetup();

  console.log(meetup.welcome("World", "Hello"));

If you run the above code, without the decorator, the output would be

Arguments Received are World, Hello
World Hello

If you run the above code, with the decorator the output would be

Arguments Received are Hello, World
Hello World; This is awesome

What is happening?

in the decorator function, the descriptor has certain properties associated with it. (Refer: pre-requisite). First, we are storing the original function in a variable (var oldValue = descriptor.value; ) . Then, we are modifying the value of the descriptor and then returning the descriptor. As you can see inside the modified function we could execute the original function with modified arguments and return a modified output.

Isn’t this Amazing?

Decorators wrap your methods, By using Decorators, you essentially have the power to manipulate an input of a function and output of a function. That means you can do magic with it!

giphy (3)

Points to Ponder

  • Decorators are called when the class is declared—not when an object is instantiated.
  • Method Decorators return a value
  • It’s better to store the existing descriptor value and return a new value. The reason behind this is that if you modify the descriptor, the other decorators which are which are modifying the behavior would not get access to the original decorator. (We will look into using multiple decorators shortly)
  • Do not use arrow syntax when setting the descriptor’s value.

What can you do with this?

  • logging
  • Apply Formatting
  • Apply Permission Checks
  • Block Overriding  of methods
  • Timing Functions
  • Rate-Limiting
  • Whatever you thought that that cannot be done while you were having breakfast
  • and the list goes on…

Hooray! Now you have written your first Decorator.


Before we move on to the other types of decorators lets look at the below concepts

Decorator Factory

You can make use of decorator factories to customize the decorator that is being applied.

Example Decorator Factory

  function leDecoratorFactory(randomData: string) {
    return (target, propertyKey: string, descriptor: PropertyDescriptor): any => {
      var oldValue = descriptor.value;

      descriptor.value = function () {
        console.log(`Calling "${propertyKey}" with`, arguments, target);
        let value = oldValue.apply(null, [arguments[1], arguments[0]]);

        console.log(`Function is executed`);
        return value + "; This is awesome; " + randomData;
      }
      return descriptor;
    }
  }

  class JSMeetup {
    speaker = "Ruban";
    @leDecoratorFactory("Extra Data")
    welcome(arg1, arg2) {
      console.log(`Arguments Received are ${arg1} ${arg2}`);
      return `${arg1} ${arg2}`;
    }
  }

  const meetup = new JSMeetup();

  console.log(meetup.welcome("World", "Hello"));

The output of the above code would be the following,

Arguments Received are Hello World
Hello World; This is awesome; Extra Data

What is happening here?

Decorator Factory takes custom arguments and returns the decorator function. Thanks to the closures, now the decorator can use the data passed into the factory function.

What can you do with it?

  • You dont have to craete multiple similar decorators
  • You could have a single point to access all differnt types of decorators

Decorator Composition

Multiple decorators can be applied to a method/class/property.

  @decorator_1
  @decorator_2
  @decorator_3("Some Data")
  class JSMeetup {
    public myName = "Ruban";
    constructor() {
    }
    greet() {
      return "Hi, I'm " + this.myName;
    }
  }

The Gist: Wrapping a gift, putting it in a box, and wrapping the box.

giphy (4)
(oooohhh ohhhh!)

Points to Ponder

  • Decorators gets evaluated from top down
  • Decorators gets executed from bottom up

Property Decorators

Property decorators are very similar to method decorators. We will get the power to redefine the getters, setters and other properties such as enumerable, configurable etc. Let’s dive into property decorators

Decorator Signature

PropertyDecorator = (target: Object, key: string) => void;

Pre-Requisite

For us to get a deeper understanding and write property decorators, we need to understand Object.defineProperty function.

To speed things up, let us look at the usage of Object.defineProperty() function.

Object.defineProperty(o, 'myProperty', {
get: function () {
return this['myProperty'];
},
set: function (val) {
this['myProperty'] = val;
},
enumerable:true,
configurable:true
});

When you were using the function Object.getOwnPropertyDescriptor() , you would have noticed that properties and methods of a class have their own properties. We use Object.defineProperty() to define them. I guess the dots would now connect.

Screen Shot 2017-06-20 at 7.36.06 AM

now let’s write a simple property descriptor

Example Property Decorator in Action

The following property descriptor will override the property myName and returns my real name all the time, along with the name given in the class.

function realName(target, key: string): any {
    // property value
    var _val = target[key];

    // property getter
    var getter = function () {
      return "Ragularuban(" + _val + ")";
    };

    // property setter
    var setter = function (newVal) {
      _val = newVal;
    };

    // Create new property with getter and setter
    Object.defineProperty(target, key, {
      get: getter,
      set: setter
    });
  }

  class JSMeetup {
    //@realName
    public myName = "Ruban";
    constructor() {
    }
    greet() {
      return "Hi, I'm " + this.myName;
    }
  }

  const meetup = new JSMeetup();
  console.log(meetup.greet());
  meetup.myName = "Ragul";
  console.log(meetup.greet());

If you run the above code, without the decorator, the output would be

Hi, I’m Ruban
Hi, I’m Ragul

If you run the code, with the decorator, the output would be

Hi, I’m Ragularuban(Ruban)
Hi, I’m Ragularuban(Ragul)

What is happening?

Property decorators take two parameters(target, key). We make use of them to redefine the property of the object using the function Object.defineProperty() .

Points to Ponder

  • There is no Return Value
  • The use of defineProperty

What can you do with it?

  • Making a property immutable
  • Setting Validators
  • Formating (through getters)
  • etc.

Class Decorators

Class Decorators basically modifies the constructor of a class. The Typescript way of doing this would be to extend the class being that is being decorated. By using class decorators, you will be able to modify/add new properties and methods to classes.

Decorator Signature

ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction;

Example Class Decorator in Action

The following Class decorator will modify the property speaker and add another property called extra .

function AwesomeMeetup<T extends { new (...args: any[]): {} }>(constructor: T) {
    return class extends constructor implements extra {
      speaker: string = "Ragularuban";
      extra = "Tadah!";
    }
  }

  //@AwesomeMeetup
  class JSMeetup {
    public speaker = "Ruban";
    constructor() {
    }
    greet() {
      return "Hi, I'm " + this.speaker;
    }
  }

  interface extra {
    extra: string;
  }

  const meetup = new JSMeetup() as JSMeetup & extra;
  console.log(meetup.greet());
  console.log(meetup.extra);

If you run the above code without the decorator, you will get the following output

Hi, I’m Ruban
undefined

If you run the code, with the decorator, the output would be

Hi, I’m Ragularuban
Tadah!

What is happening?

Class decorator takes one parameter, which is the class itself(constructor). We are essentially modifying the class by extending the class. I guess it would give you the idea.

Points to Ponder

  •  Typings are missing (you have to provide typings. an alternative would be to create a factory which return the decorated class)
  • The extended class is called once the constructor of the original class is called.

What can you do with it?

  • Logging
  • Add additional behavior in the path of object creation
  • Everything and anything that you could think

Parameter Decorator

Now, you might be thinking parameter decorator is going to be used to change the parameter of a function. But wait… Parameter Decorator is a little different.

It is used to mark the parameters that need attention. You mark the parameters and then you make actions using a method decorator.

Decorator Signature

ParameterDecorator = (target: Object, propertyKey: string, parameterIndex: number) => void;

Example Parameter Decorator in Action

  function logParameter(target: any, key: string, index: number) {
    var metadataKey = `myMetaData`;
    if (Array.isArray(target[metadataKey])) {
      target[metadataKey].push(index);
    }
    else {
      target[metadataKey] = [index];
    }
  }

  function logMethod(target, key: string, descriptor: any): any {
    var originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {

      var metadataKey = `myMetaData`;
      var indices = target[metadataKey];
      console.log('indices', indices);
      for (var i = 0; i < args.length; i++) {

        if (indices.indexOf(i) !== -1) {
          console.log("Found a marked parameter at index" + i);
          args[i] = "Abrakadabra";
        }
      }
      var result = originalMethod.apply(this, args);
      return result;

    }
    return descriptor;
  }

  class JSMeetup {
    //@logMethod
    public saySomething(something: string, @logParameter somethingElse: string): string {
      return something + " : " + somethingElse;
    }
  }

  let meetup = new JSMeetup();

  console.log(meetup.saySomething("something", "Something Else"));

If you run the above code without the decorator, the output would be the following,

something : Something Else

If you run it with the decorator, the output would be the following.

something : Abrakadabra

What is happening?

Parameter Decorator takes 3 arguments(target, key,index).  In the parameter decorator, we are essentially marking the parameters in an array in the target object (in the property myMetaData ). Nothing else.

Then, we are using the Method Decorator to read those marked parameters (in myMetaData)  and then changing the marked parameters.

Points to Ponder

  • There is no return value
  • It’s usually combined with another decorator type

What can you do with it?

  • Dependency Injection is possible
  • Mark Parameters to apply Validators and formatters

You can write one Decorator Or you Just can Use existing ones 😛

Now that you have learned about different kind of decorators and how to use them, lettuce see what are the available decorators which are out there that you can use to straightaway.

Here are some cool Decorators out there

Feel free to share if you have found any cool decorator library.


I know, it’s been a long read. Thank you for taking the time to read this. If you think you can do a better explanation or if you think that I have gone wrong somewhere, please feel free to mention them in the comment section.

Start Coding; Have Fun 🙂


References

  1. https://www.typescriptlang.org/docs/handbook/decorators.html
  2. https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md
  3. https://survivejs.com/react/appendices/understanding-decorators/
  4. https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841
  5. https://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from-novice-to-expert-part-ii
  6. https://github.com/arolson101/typescript-decorators

Application Services Tier

Modern applications are consumed by different types of users. Users also have multiple entry points to applications. For example – a user might access the same application from the mobile app and visit the application using the laptop another day. Product owners, Application architects, and developers all have to realize that this is going to be the thread in the future. Two future interfaces that are currently popularized are Chat bots (Messenger, Telegram) and Home assistants (Alex, Google Assistant).

 

Layers of the Architecture

Main three layers of the architecture include the User Interface, Application Services Tier (AST), Core Services. Your application users’ primary point of contact is the user interface. Once the user does an action on the interface, the application services tier is engaged to serve the user. Application services tier facilitates the action by invoking the required core services.

Screen Shot 2017-05-28 at 9.05.29 AM

Usefulness of AST

Application Services Tier provides quite a bit of useful features but most importantly it provides the necessary decoupling of Core Services from the User Interface. The core services set is reusable across multiple application services tiers. The same application can have multiple interfaces which could be Mobile Apps, Web Apps, or even Chatbots.

Screen Shot 2017-05-28 at 9.26.05 AM

 

Application Services Tier provides below services:-

  • Application specific logic
  • Authentication and Authorization
  • Logging and Monitoring
  • Push notifications
  • Cache
  • Session flows
  • External API Integration (Facial recognition, Voice etc)

Modern Application Architecture

Now we have to understand how the application service tier will integrate with other components. Rather than explaining it in an abstract context, I will use an example. Our application is a Food Ordering Chatbot. Our core services are provided by a third party that contains the data of restaurants and the food ordering services. How does our application look in this context?

Screen Shot 2017-05-28 at 9.42.05 AM

 

When a user first interacts with the Facebook Messenger bot, AST engages the app logic in creating a user and replying back to him with a greeting. When the user requests a restaurant recommendation with certain attributes, AST consumes the Core service, in this case, Food Delivery service to request a recommendation. AST also caches the results before returning to the user. This reduces future consumption of the core service.

Development Practices

Once our application is decomposed to the above layers, we will be able to improve our development practices as well. Testability increases since we are able to mock the Core services. An integration test suite can be completely written as if the Interface is interacting with application services tier that would connect to the mocked core services. Another integration test suite can be facilitated to test the core services. This could be used to validate the contract of the core services throughout the product incubation period.

Rapid development of the user interface is possible since the application tier is aware of the user interface consuming the data. Further more, modern technologies such as Swagger documentation makes the development practice faster with generators for Services.

Due to the decoupling of the user interface from the core services set, we are able to independently innovate and experiment with the user interface and application services tier. This gives us the possibility to iterate into Modern communication technologies such as GraphQL.

Technical Architecture of AST

Screen Shot 2017-05-28 at 12.35.48 PM

Inside the AST, there are few components. The facade component is responsible for understanding communication protocols such as GraphQL, REST, Web hooks etc. The facade component then hands over the data to a middleware chain. Middleware chain can perform the security checks, logging and caching. The app logic layer is responsible to invoke the core services. There will be several app logic components written that would support push notifications, session handling and external service integration. The cache implementation could be Redis, or MemCache. The App logic layer can utilize an ORM or an ODM to be independent of the database required.

If you look closely at this – this looks quite a bit similar to the micro-services architecture. But this architecture doesn’t require additional API managers nor Message Brokering features. Going forward, this architecture can be improved further more to add such functionality if there is a requirement.

Summary

Application Services Layer can be summarized as a pattern that can be used to iterate product development faster. Further more it provides clarity going forward in the iteration cycles due to the loose decoupling it has on the core services tier. The architecture also provides quite a bit of extension points to make the development process smoother with integration testing in isolation.

 

Mobile App Development Landscape

One Monday morning, a client reached us out to develop a multi-platform mobile app for Banking. They have built a prototype with all the screens and that was our spec sheet. “Okay, Cool”. Now we got to build this idea of theirs, which was close to 50 screens. We only got 3 months. Whoa.

Where do we start? What technology are we going to use? Are we going to go for heavily adopted tech stack in the market or are we going to bet on edge technology stack? These were the questions that were ranting in our heads.

Amidst this confusion, we thought we should get a sneak peak of every possible solution before we pick one. We then started to analyze all kind of possible solutions in hope that we would get a solution. Oh, wait… That’s a bad idea! This analysis leads us to paralysis of not making a decision. This blog post is all about how we moved on with this paralysis by analysis. (We just began the development when we finished this article 🙂 )

(The prototype  consisted of more than 50 screens; needed integrations such as camera, NFC, Location Services, Push Notifications, etc.)

 


What is Our End Goal?

 -Ideal success scenario of our struggle

Deliver the mobile app idea with perfection which ultimately satisfies our client, the end-users AND US (It’s very hard for us to get satisfied with anything:-P. You would’ve known that when you read the title of this post itself)

We believe that every creation that we work on should be of pure enthrall. We never wanted to and never will, create something that we aren’t proud of saying that we made this.


Let’s Traverse the Decision Tree…

 

Native Apps: Apps developed through native development languages like Java, Objective-C, or Swift.
Hybrid Apps: Apps developed with web technologies which reside inside a native container which gives API access to native plugins
Almost Native Apps: Apps which runs on JavaScript virtual machines but takes advantage of native UI components


Native Apps

If you’ve come to this point of this article, you would know what we are going to talk about. YES! IT’S DEVELOPMENT NIGHTMARE. Writing the same app in different languages is like going through the same hell again and again. You can imagine how hard it would be to undergo maintenance and upgrades with different code-bases.

Of course, it would be a super-duper dapper thing if we build and maintain pure native apps. But, in our eyes, we believe that it’s not worth the effort and not feasible for the Project X with the time duration we have.


Oh, wait… Xamarin to the Rescue

 

Xamarin backed by Microsoft, offers you the ability to share 75% of the codebase while giving you the freedom to design the user interface for different platforms separately. It’s just WOW, isn’t it?

Native User Interfaces, Native API Access, Native Performance. And now it’s made FREE!
Yes. Xamarin would be a brilliant choice, but then again it’s not easy as we speak. Here are the cons which made us look into other options.

  • Time that we have in hand ( we have only 3 months)
    – Development overhead is very high
    – Testing and developing UI for different platform takes time
    – Certain requirements of the client may lead us to spend time in writing libraries which we don’t want to
  • The solution that we are offering needed rapid development
  • Xamarin community is not large as we expected.
  • Our Core team does not love c# language development ☹

We don’t want to discuss further. We just moved on to other options as it required more time for us to deliver the app

(We might suggest going with Xamarin if you have enough resources and development period)

Let’s Talk Hybrid

What we are going to discuss is basically apps whose UI Components resides in a web view container. Here’s the first pitfall: the web-view consists of a DOM and that leads to slower apps when compared to native.

Okay. We know it’s going to be slower, let’s see how this solution gets the upper hand.

  • Progressive App Development
  • Almost all native features are available through wrappers
  • Web Technologies (HTML5, CSS, and JS are our friendly Heroes)
  • Maintaining is easy as pie (at least when compared to other solutions)
  • Community Support is unbelievable
  • Etc.

Now we need to analyze whether we can compromise on the pros and cons. But before that…

Let’s look at the options available (at least the ones which interested us)

  • Ionic 1.3 with angularJS
    – Has an excellent community support; it’s been there for ages
    – Angularjs is our friend (but not)
  • Framework 7
    -Impressive and well documented, but lacks community support
    -Learning curve exists as it features its own framework
  • Sencha UI, Appcelerator
    -Needs a learning curve
    -Lesser community support
    -It’s not free…
  • Build our very own theme components
    -It’s very promising. But is it worth the effort?
  • Ionic 2 with angular 2
    -Hmm… I think this should do… but… Oh, wait… Ionic 2 is still in beta

IONIC 1

While we were discussing the options available for hybrid app development. The community support of ionic and the framework itself impressed us. First, we dived into ionic 1.3.

  • Good documentation;
  • The framework is mature enough
  • Tech stack we already knew
  • Development Planning was easy peasy
  • We knew each and every bit of the whole development challenges

So we thought, without any further analysis we should pick ionic 1.3

Rollback. Rollback. Rollback

Ionic 1.3 is built on angularJS. We have a terrible experience with mobile app development with angularJS. Considering the prototypes and the complexity of the app, we were able to forecast the performance drawback which we can’t afford to give in the app.

IONIC 2

With Angular 2 just released around the corner, the architecture of Angular 2 gave us a promising performance improvement. Ionic 2, on the other hand, has much better UI and give native feeling to the app which is ABSOLUTELY FANTASTIC.

Before we lock Ionic 2, we had our concerns

  • After all, it’s a hybrid app, it will not hit very high on performance
  • Ionic 2 is still in beta
  • Angular 2 it’s a new stack we should learn

So why we were not reluctant to keep the bet on ionic 2?

  • Ionic 2 recently (relative to 20/12/2016) has locked their API which means we won’t be having any major issues with regards to their framework.
  • The phones that we are targeting are phones with almost good performance (ideally, Galaxy S3 and later versions).
    In this context, will the performance be a big barrier? We do not think so. This is the reason behind it -> “A healthy community won’t back a Mobile framework if it doesn’t guarantee the expected performance”

So, we are actually betting on the community behind angular 2 and ionic 2 that it would be the best solution for this mobile app development work.

And it starts… starts with angular 2

 

We began exploring angular 2 and Ionic 2 and started to build a throwaway prototype. While the prototype is in process, we mainly focused on re-thinking the UX part of the app and we started to sketch the UI with sketch.io so that our client and our development team are on the same page for this Project X (We cannot afford any last minute changes as the development period as the timeline is very critical)


Almost Native Solutions

While we continued with Ionic 2, we thought of exploring the next branch: Almost-Native Solution, before we actually build the app.
React Native and Native Script were on our plate to discuss…

Both Frameworks boasts about native performance. They use JavaScript to power the logic behind while UI is handled with native UI components.

This sounds very promising!

  • Lesser development time
  • Known Technologies (almost)
  • Rising Community Support
  • Performance Edge

 

It is very hard to pick between React Native and Native Script. It will always end up as a battle between Angular 2 vs React JS.

We went on analyzing the available components and libraries with respect to project X in hand

Our Concerns

  • Available Native Plugin Integrations
    – Barcode Scanner
    – NFC
    – Card.io
    – Push Notifications
    – Fingerprint Scanner
    – Camera API
    – Voice API
    – Google Maps
    – Bluetooth
  • Ability to custom style components
  • Stability in the APIs provided
    (we don’t want the application to break with future versions of the framework)
  • That’s almost I can think of now (Of course there can be any unseen devil)

Thinking from the point of our concerns, both React Native and Native Script are Ideal choices.

  • +1 for React Native because it already has Card.io plugin where Native Script doesn’t have it yet.
  • +1 for Native Script for styling options given out.

It’s a tie again!


Final Verdict

 

What do we choose…? Ionic 2? React Native? Or Native Script?

We Picked Ionic 2… Badum-tish!

It’s hard to pick the best out of the options we have on the plate. All we can do is, pick the best for the project (At least, hope that its the best)

Why Ionic 2?

We just picked few points as to why…

  • Ionic 2 has bigger community support
  • All Plugins which needed are already available
  • We can deploy a windows app as well
  • We have already learned the tech-stack by this time
  • Typescript; Better Tooling!
  • A Big +1 for styling and customization (you know why 😛 )

 

Is That All?

 

One of the main reason for us to go for Ionic 2 is Angular 2! Wondering Why? Here’s it….

In future, if the client decides to go native, Native Script will be there for the rescue. We believe Native Script also would support windows apps by that time. All the providers and business logic, doesn’t need to be re-written again! We may just have to create the UI components and rewire the entire app.

Don’t you think that this would be the best game plan?

Conclusion

The two key things in which we are keeping the bet are

  1. Healthy Community is Key #1
  2. Angular 2 and Typescript — We think the duo is Super Brilliant

 

Disclaimer 😛

This is a story and the flow of the article is aimed at our mindset when we were thinking about each solution. Get ready to be confused 😛