AdS Google
Skip to content

Front-end frolics @ Coverfox. ‘Awesome’ and ‘cool’ are certainly not… | by Gagan Jakhotiya


‘Awesome’ and ‘cool’ are certainly not the words that come to one’s mind when you think of buying an insurance policy. It has been a boring space since stone age (if insurance was ever that old a concept). But insurance occupies an important part in one’s life (and livelihood) and has to be understood and dealt with every now and then. This is where we come in, to help you out.

We’re here to make the process of buying an insurance policy as lucid as possible and a little more delightful.

AdS Google

Front-end forms the base of User Experience. In the past few years, the front-end space has been more dynamic than it had been at the beginning of the world wide web. And Team Coverfox has actively been exploring this fast-growing domain.

We, at Coverfox, have worked with AngularJS, ReactJS, KnockoutJS and a bunch of other cool libraries. But with the ever-changing designs, we needed to come up with a development architecture that kept our business stable while catering to development of new designs and business requirements. And since we’ve tied up with a bunch of other cool firms out there, we wanted a hassle-free sharing process for our product interfaces.

Modularity and re-usability of code are two of the essential factors needed for an efficient development process. ReactJS leveraged both of these factors by coming up with a compositional application flow. And, using ReactJS along with Facebook’s Flux Development Architecture ensures that the business logic needn’t rely on any particular development technology.

Also, ensuring data integrity can be a major issue when systems grow complex and parameters start stacking up. So it makes sense to use a statically typed language while still enjoying the flexibility of JavaScript, which is loosely typed language. TypeScript and Facebook’s Flow are the two most popular options available for this. While Flow only has a limited online community, TypeScript has built a huge user base. DefinitelyTyped is a community where TypeScript users come to contribute and make use of already available Type Definitions. Also, TypeScript supports syntactical perks such as those of ES6, ES7 and more.

So, to sum it up, we work with our own, simple implementation of Facebook’s Flux Development Architecture. We make use of Typescript to write statically typed React Components and Application Stores. And, lastly, for the build process, we utilize uber-cool features of Webpack to bundle, part, and pre-process our application source.

Getting one’s to head wrap around a particular development architecture is not as easy as it may seem. Flux simplifies this part by following the path of primal integration flow of web applications which exists between back-end and front-end. One easy way to look at it is to treat Stores as back-end, UI components as front-end and Actions as server requests.

Actions are the simplest unit of code in a Flux-based architecture. Actions are soup methods that simply provide blueprint of data required to perform a notable action in the application. Using this on top of a statically typed language makes application less prone to errors and easier to work with.

In our implementation, a typical Action set looks something like this:

Application Actions

Here, the UniverseActions class contains all possible Actions that can be performed in the application. One can have multiple Action classes. Actions are needed at both Store’s and UI Component’s end to create the link between them. You’ll see how we’re doing that in a bit.

Moving on, Stores are basically classes that hold a set of public and private methods. Public methods do not modify any relevant data. They usually just return data that UI Components need. Private methods are called upon internally by an Action-handler-method. Each Store must have an Action-handler-method which caters to Actions that are called by UI Components.

This is how a simple Store would look like:

Application Store

Continuing on the idea of Stores, an application can have n-numbers of stores. Multiple stores are supposed to segregate the core business logic into several independent (as much as possible) chunks. _namespace is passed at the time of instantiation of a Store, which allocates a memory location to store. Any data relevant to that Store is maintained under the given namespace.

Data in a Store can either be persistent across sessions or temporary to a visit. Persistent data can have any underlying native API. We make use of LocalStorage, but it can be used with other APIs as well. More than one store can share the same namespace, but logic must carefully be written in such cases to make sure data is not overridden.

In the above code, handler is the method that caters to all the dispatched Actions. Every Store must implement the handler method. Below is the list of methods [provided by BaseStore] that are available to any Store.

  1. get(key?: string) — To get a persistent data
  2. set(obj: {[key: string]: any}, preventEmit?: boolean) — To persist a set of data
  3. setValue(key: string, value: any, preventEmit?: boolean) — To persist data against a particular key
  4. emit() — To notify subscribed UI Components of change(s) in data
  5. waitFor(…stores: BaseStore[]) — To wait for particular Store(s) to perform a dispatched Action first

Note:

  • preventEmit argument in the above set and setValue method is to control a default change event that fires every time after setting some data.
  • If no key is passed in the get method, the method returns all the data under the Store’s given namespace.

Next on the list is UI Components. UI Components are dumb React Components deprived of any business logic. Their State is updated based on a Snapshot Function that sets Component’s state every time any Store, which a Component is subscribed to, emits an event. For this to happen, Component is required with (at the time of instantiation) the array of Stores it wants to subscribe to and the Snapshot Function it is going to use.

A typical UI Component looks like this:

UI Component

Every Component that extends BaseComponent re-renders every time a Store, that they are subscribed to, emits. On emit, Components pick up the latest data from the Stores by executing the snapshot function. And, in this way, completing its data cycle.

Our flow is optimized to support various frequently used features that an SPA works with; such as sharing data across session, client-side routing, lazy loading, etc. While BaseStore deals with the underlying, native, data sharing API, BaseComponent can be used with React Router to easily integrate client-side routing in the application. URL updates based on component’s state work seamlessly with BaseComponent. Also, thanks to the huge JavaScript community, making use of Webpack plugins and loader (such as ts-loader, bundle-loader, CommonsChunkPlugin, etc) makes it easier to get this all up and running without much effort.

The flow may look tedious to someone who is not used to Flux. But, in the long run, it really helps. For instance, if one has the business logic ready and stable, it is super simple to build new UI. And, if tomorrow one wishes to move to some other development technology (say, Web Components :D), all he has to do is rewrite all the UI Components. The business logic remains stable and intact as before. And so, updating the application can be a gradual process instead of a bulk overnight change.



Source link

AdS Google