Wednesday, October 24, 2018

Let's build clean and Fast Angular application


The wait is over and Angular 7 is out, finally time has come to write about some tips to build fast angular application.In this blog i will share my experience with practices that you need to follow when you are starting a new project.

There are three primary things important when you are starting to build an application with Angular.
  1. Project Architecture
  2. Application Infrastructure
  3. Conventions,Formating and Tooling

CONVENTIONS,FORMATTING AND TOOLING : 

Always place the Angular application outside your backend code

Keep the application in its own repository so that can be deployed/versioned separately. It will also help in tooling. One key rule is to treat it as a real application.

Use VS Code for best experience 

Encourage your team to switch to VS Code which has immense support for development with Angular. It has strong support for extensions used in Angular projects and well regarded by front end community.

Use Tooling

It will kill all the disagreements. Use VS Code extensions such as TSLint, Angular Language servicePrettierEditorConfig and SCSS intellisence. 


Naming and Syntax Conventions

Always use Singular for Modules and Singular or Plural for components/services/directives and pipes


Use Angular style commit messages

'feat(notification.service): add display param'
'refactor(order models): rename couponId to couponCodeId

Use Codelyzer to do statistical analysis on Angular/Typescript code

It's a set of tslint rules for static code analysis of Angular TypeScript projects. If you are doing Continous deployment configure with your pipeline.


Follow Consistent component/directive/service/module

If you are using Angular-Cli always follow the same pattern to generate the necessary files so that it will be consistent throughout the application.


Absolute path for ES Modules

Alwasy use absolute path that would help in refactoring(moving files around or renaming) and very easy to organize files.


Do not use null and assign default values 

In the templates always use safe navigation type operator which can help in preventing the following annoying erros "cannot read property "name" of undefined"

Choose intelligent defaults and be consistent with them 

'' for string - declare string with default value ""
0 for number - declare numbe with default value 0
[] for arrays - declare array with default value []


Build small reusable components

Dont make your component code go more than 300 lines. Split the pieces that can be reused in a component and make them as a new component. The component should be made as dumb as possible. It should not dependent on any inputs or outputs provided it , it should work simple. General rule of thumb is to make the last child in the component tree to be the dumbest. Reusable components reduce the duplication of code and you can make changes easily.

Components should deal only with the presentation logic Dont have logic other than the presentation logic. Components are designed for presentational purposes and only should focus on what the view should do.Business logics should be separated out to services/methods from the presentation/view logic.


Use trackBy in ngFor Loops 

DOM manipulations are always expensive, immutable practices always generate a new collection which will result in bad performance. When your array changes, Angular will be rendering the whole DOM tree, when you use trackBy, it will know which elements has changed and will make changes only to those particular elements.


const vs let 

Make use of let and const wherever its appropriate. It will help a lot in identifying issues when a value is resassigned to a constant accidently with a compile error and it improves the readability of the code.

Pipeable operators 

With Angular version above 5.5 , you can use pipeable operators which are tree-shakable (only the code need to execute will be included when they are imported) and it will be easy to identify unsed code in the component files.


Subscribe in template 


Rather than subscribe in service or async popes unsubscribe themself automatically it will make the code simpler by stopping the need to manually manage subscriptions which could cause a memory leak. When using subscribe, the risks can be eliminated by using a lint rule to detect unsubscribed observables.


Clean up subscriptions 

When you subscribe in the component to observables, make sure you unsubscribe from them completely with operators like take,takeUntil,Unsubscribe etc


Use appropriate Operators 

switchMap: when you want to ignore the previous emissions when there is a new emission

mergeMap: when you want to concurrently handle all the emissions

concatMap: when you want to handle the emissions one after the other as they are emitted

exhaustMap: when you want to cancel all the new emissions while processing a previous emisssion


Stop using any:type everything in the code

Always declare variables or constants with a type other than any. This is the advantage that you have with Typescript when you have good typings in your application which makes refactoring easier and safe and also avoid unintented issues.


Use lint rules as you need

TSLINT has various options built in already like no-any, no-magic-numbers, no-console, etc that you can configure in your tslint.json to enforce certain rules in your code base


Dont Repeat Yourself 

One of the common mistake that i did as a developer was copy paste the same code in all components. Do not repeat or have the same code in different places in the code base. Extract the repeating code and make them as a generic method which could be used in diferent components.


Avoid Logic in component templates

Place the logic in the component file rather than on the template such as && condition since it cannot be possible to unit test also it is prone to more bugs when changing template code


APPLICATION INFRASTRUCTURE

Lazy load everything - When you are building application with large number of modules always do lazy loading which could improve your application performance by large margin. Angular CLI makes this easy and helps break up your app into logical bundles. With Lazy loading users only pay for what they want. For example, Sensitive (admin only) code will not be downloaded for users that don't have access.

Analyze your bundle - If you are using any bundling mechanism always analyze the size of the bundle generated. You can use webpack-bundle-analyzer for example and you can improve the performance there on.

Install source map explorer

npm install -g source-map-explorer

Build with source map
ng build --prod -sm

Inspect your bundle
source-map-explorer dist/vendor*.js

Debug.Service.ts - It is always good to have a common debug service to assist with the development. This service could replace the calls to console.log.  You can use Visual studio extension codelens to track down the calls with console.log.This service can be toggled at run time with local storage value and needs to be switched off with production builds.

RxJs Operators: When using it becomes handy to handle so many operations with Rxjs operators. Always remember to include/import only the things you need. Also make sure to add noUnusedLocals in the tsconfig.

Use ES Modules for helper functions: With ES Modules it is really easy to import only available when thy are needed.

Keep environment values in environment files: It becomes really easy and very helpful to manage environment values when it comes to continous improvement and continous deployment. 

Avoid Bas classes / Inheritance: Even though Angular is build with Typescript, many of the developers tend to use services from a base class. This should be only if necessary. It will result in restricting the flexibility as when your app grows and use cases changes.
Also create a utility.services.ts to contain all the base helper services. For ex: debug.service.ts , notification.service.ts  session.service.ts can be placed within utility.service.ts which helps in preventing app wide changes to base constructor.

Use Obseravable/State Management Patterns: It is really important to follow Redux patern (RxJS) to have a better state management in application. Also in components use ngUnsubscribe for complex Observable management in Components. Use shareReplay operator and/or async pipe for simpler cases

More things to consider on Application : Always consier browser caching and application versioning. Test the update process and the experience across browsers. Always figure out user experience and continously work on it. Use global error handler to store repor errors to API and do not access Document or Window Objects manually.

ARCHITECTURAL THOUGHTS &  PROJECT STRUCTURE 
  • One of the primary thing that you need to consider before starting a project is the architecture on how to build flexible,simple,fast application. It needs lot of planning and consistency to get the basement correct. Building things is really hard enough. When it comes to building Angular application i would recommend to follow the following Guidelines
  • One best place to start with good practices is by following the recommended style guide. You need to take what works for your team and skip what does not work. Also try to learn from others mistakes or any other projects that you've already worked with. 
  • While designing module,s it is really important to know about how to structure your modules and what should go under Feature/Core/Shared Modules.


  • Keep a flat file structure as long as possible which means you should not add hierarchy with less than 20 files and you can always move files as the app grows larger.
  • Maintain your application version using the package.json which could be embeded in your app.
  • Use package management toolingto guarantee reproducible dev environment and builds.
  • Set custom host for the application by changing the default url.
  • Use proxies if you are integrating with an API. 
  • Lets look at what you can do while implementing the above architecture in your application

Follow this repository in order to get started

The above are the some of the most important practices that you need to follow when you are starting a  new project with Angular. Hope this helps someone out there. 

Saturday, October 20, 2018

Resolve Issue : ASP.NET Core 2.1 runs fine locally but when publishing to Azure says “An error occurred while starting the application.”

After building my first production ready application with ASP.NET Core 2.1 and tested locally when i tried to deploy for the first time on Azure, i was stuck with the following page.
Since many different problems can cause this error page, I would strongly recommend the following in order to determine the root cause quickly and easily, without meddling with Azure.
You can enable extremely helpful developer friendly error messages at startup by setting the .UseSetting("detailedErrors", "true") and .CaptureStartupErrors(true) actions in your Program.cs file.
public class Program  
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .CaptureStartupErrors(true)
            .UseSetting("detailedErrors", "true")
            .UseStartup<Startup>()
            .Build();
}

With the above settings publish your application to Azure.Once you identify the rootcause and resolve your issue, Thes above settings should be removed as soon as your troubleshooting is complete so as not to expose your application to malicious attacks. 
Hope this helps someone out there.

Saturday, September 15, 2018

Ace Angular Interview in 20 minutes - PART1

This should help all the Angular developers out there to test yourself on the knowledge on Angular. I have listed down the concepts/questions from various sources such as Stackoverflow,Medium etc. Will be continuing this with 2 more posts.

1. What's new in Angular 6
  • Angular Elements - Angular Elements is a project that lets you wrap your Angular components as Web Components and embed them in a non-Angular application.
  • New Rendering Engine: Ivy - increases in speed and decreases in application size.
  • Tree-shakeable providers - a new, recommended, way to register a provider, directly inside the @Injectable() decorator, using the new providedIn attribute
  • RxJS 6 - Angular 6 now uses RxJS 6 internally, and requires you to update your application also. RxJS released a library called rxjs-compat, that allows you to bump RxJS to version 6.0 even if you, or one of the libraries you’re using, is still using one of the “old” syntaxes.
  • ElementRef - in Angular 5.0 or older, is that the said ElementRef had its nativeElement property typed as any. In Angular 6.0, you can now type ElementRef more strictly.
  •  Animations - The polyfill web-animations-js is not necessary anymore for animations in Angular 6.0, except if you are using the AnimationBuilder.
  • i18n - possibility to have “runtime i18n”, without having to build the application once per locale

2. Difference between "Constructor" and "ngOnInit
  • The Constructor is a default method of the class that is executed when the class is instantiated and ensures proper initialization of fields in the class and its subclasses.
  • ngOnInit is a life cycle hook called by Angular to indicate that Angular is done creating the component. We have to import OnInit in order to use like this (actually implementing OnInit is not mandatory but considered good practice).

3. Difference between "declarations", "providers" and "import" in NgModule
  • imports makes the exported declarations of other modules available in the current module. It is also used to import supporting modules likes FormsModule, RouterModule, CommonModule, or any other custom-made feature module.
  • declarations are to make directives (including components and pipes) from the current module available to other directives in the current module. Selectors of directives, components or pipes are only matched against the HTML if they are declared or imported.
  • providers are to make services and values known to DI. They are added to the root scope and they are injected to other services or directives that have them as dependency.

A special case for providers are lazy loaded modules that get their own child injector. providers of a lazy loaded module are only provided to this lazy loaded module by default (not the whole application as it is with other modules).

Example : 

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';


import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';
import { UserComponent } from './components/user/user.component';
import { StateService } from './services/state.service';    

@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [ StateService ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }


4. Ahead Of Time Compilation (AOT)

 Angular Ahead-of-Time compiler pre-compiles application components and their templates during the build process.Apps compiled with AOT launch faster for several reasons
  • Application components execute immediately, without client-side compilation.
  • Templates are embedded as code within their components so there is no client-side request for template files.
  • You don't download the Angular compiler, which is pretty big on its own.
  • The compiler discards unused Angular directives that a tree-shaking tool can then exclude.
  • Also has small bundle size and faster load time.

5. Need of lazy loading modules in Angular.

Lazy loading is useful when the application size is growing. In lazy loading, feature module will be loaded on demand and hence application start will be faster.To load a feature module lazily we need to load it using loadChildrenproperty in route configuration and that feature module must not be imported in application module. 







Saturday, August 4, 2018

A checklist for building Angular web applications in the correct way

Hey guys, There has not been a  proper resource to have a checklist to make sure that applicaiton is flawless.I decided to write a simple tips on checklist items needed before you deploy your app to production.Following are a few Angular Code Review Checklists useful while doing a peer review of Angular code. Make sure to check these when you are building a production ready application


#1 - Code Modularity  
Layered Code with good Modularity.
#2 - Component per File 
 Each file must not contain more than one Component/Controller, etc.
#3 - Routing
Always configure routing with lazy loading
#4 - Shared Resources at Centralized Location
Store images/language translations under assets
#5 - 3rd Party Libraries 
 If you are integrating with any 3rd party libraries make sure to check for Security Flaws
#6 - Data Security 
Use  Encryption of Sensitive Data 
#7 - Offline Data Security
Consider security if you are storing Data in localstorage or session storage.
#8 - Cookies Data and Handwiring of Secrets
 Security Flaws
#9 - Do not use pipe / functions in the template
Calling function binding in the template will lead to  performance issue
#10 - Change Detection + State Management & Reactive Extensions 
Use RxJS, NgRx/Store (or Redux)
#11 - JavaScript or TypeScript
 Stick to ONE & Avoid Hybrid
#12 - Building/Packaging with WebPack (or similar)
 Bundling, Chunking, Treeshaking, Minification, Uglification, Compression
#13 - ECMAScript Compatibility - ES7 (2016)
#14 - Angular Style Guide (Official Reference) 
#15 - AsyncService 
 Adequate and Appropriate use of it.
#16 - Hierarchical Components, Models, Interfaces, etc. (Inheritance Approach)
#17 - Constants
No-Scattered Hard-Coded constants data but must be at one place.
#18 - Images, Fonts, Other Static Files -
Place them in respective directories and not scattered across.
#19 - TSLint.json 
To follow Angular Style Guide in order to run SonarQube or Codelyzer. Follow https://github.com/Angular-Projects-V-1-to-X/codelyzer
#20 Finally if you need to improve Performance - https://github.com/mgechev/angular-performance-checklist

Hope it helps all the developers out there.

Sunday, May 27, 2018

Streaming Live Tweets from Twitter to CosmosDB


This is time for another blog on cosmosdb explaining how to stream tweets from twitter using hashtags and store them in cosmosdb in real time. You should be able to setup and run this demo within 15 minutes.

Pre-Requisites Needed:

I have the following in my local environment , hope you guys have already have😊, if not start setting up.

·                  Windows 10 OS
·                  Python 2.7
·                  Visual Studio Code or PyCharm (Any editor)
·                  Azure subscription


Ok folks let’s get started.

Step 1: Install Python

Hope you have already installed Python in your system , if not download and install from here. Once you install run the following command and see if its properly installed.

Step 2: Install Tweepy and PyDocumentDB

Install the following libraries needed. 

Tweepy:

Tweepy is a python package which is easy to use for accessing the twitter api. he API class provides access to the entire twitter RESTful API methods. Each method can accept various parameters and return responses. Install it with the following command,

 Pip install tweepy  

If you get an error 'pip' is not recognized as an internal or external command. You should set the path as follows,

C:\>set PATH=%PATH%;C:\Python27\Scripts

Now you should be able to install it without any issue,

Pydocumentdb:

As mentioned above we will be storing the tweets in Azure’s cosmosdb , In order to do that we need the python package for cosmosdb which is pydocumentdb. Install it with the following command. 


Pip install pydocumentdb

Now we have everything needed. Lets dive into coding.


Step 3:  Creating Listener to invoke the cosmosdb client

Create a listener named CosmosDBListener with the following methods

__init__ Initializes the client to make sure the connection is available.

On_data will load the data retrieved from the stream and write to the Cosmosdb.

On_error will throw if there is any network/key issues on console.

from config import *
import json
from tweepy.streaming import StreamListener

class CosmosDBListener(StreamListener):
 
    def __init__(self, client, collLink):
        self.client = client
        self.collLink = collLink
        
    def on_data(self, data):
        try:
            dictData = json.loads(data)
            dictData["id"] = str(dictData["id"])
            self.client.CreateDocument(self.collLink, dictData)
            return True
        except BaseException as e:
            print("Error on data: %s" % str(e))
        return True
 
    def on_error(self, status):
        print(status)
        return True


Step 4: Stream data from twitter to cosmosDB

Lets create the real code to connect to twitter and get the related tweets for several hashtags. We will need to authenticate with tweepy to get the twets, so pass the consumer secret and access secret to the api as follows.

    auth = OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_secret)
    api = tweepy.API(auth)

Set the connection policy for cosmosdb and create a client as follows,
    connectionPolicy = documents.ConnectionPolicy()
    connectionPolicy.EnableEndpointDiscovery 
    connectionPolicy.PreferredLocations = preferredLocations

Next step is to read the tweets as follows , we are using .filter method to get tweets related to particular hashtags.

client = document_client.DocumentClient(host, {'masterKey': masterKey}, connectionPolicy)
dbLink = 'dbs/' + databaseId
collLink = dbLink + '/colls/' + collectionId

twitter_stream = Stream(auth, CosmosDBListener(client, collLink))
twitter_stream.filter(track=['#CosmosDB', '#Microsoft', '#MVP', '#BigData', '#DataScience', '#Mongo', '#Graph'], async=True)


Step 5: Creating configuration file

Create the config file with the following values,

# Enter CosmosDB config details below.
masterKey = ' ' 
host = ' '

#Enter your database, collection and preferredLocations here.
databaseId = 'tweepyDemo'
collectionId = 'tweets'
preferredLocations = ''

# Enter twitter OAuth keys here.
consumer_key = ''
consumer_secret = ''
access_token = ''
access_secret = ''

 You need to have CosmosDB account on azure to get the master key and host values, if you are stuck , read my previous blog on How to setup cosmosdb account


You also need to register the script as a new application at twitter developer portal. After choosing a name and application for your app, you will be provided with a  consumer key , Consumer secret, access token and access token secret - which need to be filled into  the above config.py to provide the app programmatic access to Twitter.




Step 6: Run the script

That’s it folks now if you goto command prompt and run the following command,

py cosmosdbdriver.py


You should see the tweets coming into your cosmosdb collection as follows.



Tweets you need are now in your cosmosdb and use them for further analysis as you need. Hope it helps someone out there. If you are stuck at anypoint, look at the complete code from here.