Clean Angular

tally_b

tallyb

A Collaboration platform between Brands and Retailers rs

Why? 

Good Taste Code

Code SMELLS

Function

You

TGSTYNTWA

deleteHero(hero: Hero, event: any): void {
    event.stopPropagation();
    this.heroService
      .delete(hero)
      .then(res => {
        this.heroes = this.heroes.filter(h => h !== hero);
        if (this.selectedHero === hero) { this.selectedHero = null; }
      })
      .catch(error => this.error = error);
  }
deleteHero(heroToDeleteInController: Hero, event: any): void {
    event.stopPropagation();

    let d = heroToDeleteInController
    this.heroService
      .delete(d)
      .then(res => {
        this.heroes = this.heroes.filter(h => h !== d);
        if (this.selectedHero === hero) { this.selectedHero = null; }
      })
      .catch(error => this.error = error);
  }

Function

  • Too many parameters

  • Long code

  • Long identifiers

  • Short identifiers

  • Excessive data return

Component / Service

You

TGSTYNTWA

import { Hero } from './hero';
import { HeroService } from './hero.service';

constructor(
    private router: Router,
    private heroService: HeroService) {
  }
import { Hero } from './hero';
import { HeroService } from './hero.service';

import { Headers, Http, Response } from '@angular/http';

import {CountryService} from "./country.service";

constructor(
    private router: Router,
    private heroService: HeroService,
    private http: Http 
    private countryService: CountryService)
 {
  }

YOU

<md-content layout="row" layout-align="center start" layout-fill layout-margin>
    <div layout="column" flex flex-md="50" flex-lg="50" flex-gt-lg="33" class="md-whiteframe-z2">
        <md-toolbar class="md-primary" color="primary">
            {{modeData.title}}
        </md-toolbar>
        <div layout="row" layout-margin>
            <p class="md-body-2"> {{modeData.description}}</p>
        </div>
        <form [formGroup]="form" (submit)="onSubmit(form.value)" layout="column" layout-padding layout-margin>
            <md-input formControlName="email" type="text"  placeholder="Email" aria-label="email">
            </md-input>
            <md-input formControlName="password" type="password" placeholder="Password" aria-label="password" *ngIf="mode !=='recover'">
            <md-hint align="start">Minimum 8 characters with 1 letter and 1 digit</md-hint>
            </md-input>
            <div layout="row" layout-align="space-between center">
                <button md-button [routerLink]="['/recover']" *ngIf="modeData.recover">Forgot password?</button>
                <button md-raised-button class="md-primary" type="submit" aria-label="login" [disabled]="!form.valid">Sign In
                </button>
            </div>
        </form>
        <div [hidden]="!error">
            <md-toolbar class="md-warn" layout="row" layout-fill layout-padding layout-margin>
                <p class="md-body-1">{{ error }}</p>
            </md-toolbar>
        </div>
        <md-divider></md-divider>
        <div layout="row" layout-align="center-center">
            <button md-button [routerLink]="['/signup']" *ngIf="modeData.signup">Need an account?</button>
            <div flex> </div>
            <button md-button [routerLink]="['/login']" *ngIf="modeData.login">Already a User?</button>
        </div>
    </div>
</md-content>

TGSTYNTWA

<md-content layout="row" layout-align="center start" layout-fill layout-margin>
    <div layout="column" flex flex-md="50" flex-lg="50" flex-gt-lg="33" class="md-whiteframe-z2">
        <md-toolbar class="md-primary" color="primary">
            {{modeData.title}}
        </md-toolbar>
        <div layout="row" layout-margin>
            <p class="md-body-2"> {{modeData.description}}</p>
        </div>
        <auth-form></auth-form>
        <auth-error [message]="error"></auth-error>
     <md-divider></md-divider>
     <auth-nav [layout]="login"
    </div>
</md-content>

Component / Service

  • Too big

  • Feature envy

  • Inappropriate intimacy

  • Cyclomatic complexity

  • FreeLoader

Application

You

TGSTYNTWA

Text

YOU

Text

TGSTYNTWA

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'navbar',
  templateUrl: './navbar.html',
  styleUrls: ['./navbar.css']
})
export class navbarComponent implements OnInit {

  @Input() label: string;
  @Input() user: boolean;
}
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'navbar-with-user',
  templateUrl: './navbar-user.html',
  styleUrls: ['./navbar.css']
})
export class navbarComponent {
}


import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'navbar-without-user',
  templateUrl: './navbar-without-user.html',
  styleUrls: ['./navbar.css']
})
export class navbarComponent {
}

The Guy...

You

Component

Data Service

Component

Component

Component

Data Service

Component

Component

The Guy...

You

Component

Component

Component

Component

TGSTYNTWA

You

Application

  • Few Modules

  • Similar Modules

  • Few Components

  • Duplicate Components / Services

  • Complex Data Management

Really?????

CompanyCtrl.prototype.getFinanceReports = function () {
        if (this.company) {
            this._CompanyProxy.getFinanceReports(this.companyId).then(function (data) {
                this.company.financeReports = data;
                this.setFinRepGridHeaders();
            }.bind(this));
        }
        else {
            this._dataStorage
           .companies.add(this.companyId)
           .load()
           .then(function (company) {
               this.company = company;              
               this.setFinRepGridHeaders();
           }.bind(this));
        }
    }

    CompanyCtrl.prototype.getTradeData = function () {
        if (this.company) {
            this._CompanyProxy.getTradeData(this.companyId).then(function (data) {
                this.company.tradeData = data;
                if (this.company.tradeData) {
                    this.changeDirection = this.checkSign(this.company.tradeData.PercentageChange);
                }
            }.bind(this));
        }
        else {
            this._dataStorage
           .companies.add(this.companyId)
           .load()
           .then(function (company) {
               this.company = company;
               this.setFinRepGridHeaders();
           }.bind(this));
        }
    }
    Company.prototype.getShareHolders = function () {
        return proxy.getShareHolders(this.id).then(function (data) {
            this.shareHolders = data;
        }.bind(this));
    };

    Company.prototype.getCompanyDetails = function () {
        return proxy.getCompanyDetails(this.id).then(function (data) {
            this.companyDetails = data;
        }.bind(this));
    };

    Company.prototype.getSecurities = function () {
        return proxy.getSecurities(this.id).then(function (data) {
            this.securities = data;
        }.bind(this));
    };

    Company.prototype.getIndices = function () {
        return proxy.getIndices(this.id).then(function (data) {
            this.indices = data;
        }.bind(this));
    };

    Company.prototype.getManagementAndSeniorExecutives = function () {
        return proxy.getManagementAndSeniorExecutives(this.id).then(function (data) {
            this.management = data;
        }.bind(this));
    };

    Company.prototype.getFinanceReports = function () {
        return proxy.getFinanceReports(this.id).then(function (data) {
            this.financeReports = data;
        }.bind(this));
    };

Lint / Style Guide / Codelyzer

http://codelyzer.com/

https://github.com/mgechev/codelyzer

Iterate

Spare Eyes

Think

Clean Angular

By Tally Barak

Clean Angular

  • 1,037