Sunday 1 July 2018

Create your custom HTML DOM in Angular.

you have to implement the methodDomSanitizer from to@angular/platform-browser make your custom element a trusted HTML tag.
You can learn more about Angular elements here
import { DomSanitizer } from '@angular/platform-browser';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-dashboard',
template: `<div [innerHtml]="content"></div>`
})
export class DashboardComponent implements OnInit {
content: any;

constructor(private _domSanitizer: DomSanitizer) {
}

ngOnInit() {
this.content = this._domSanitizer.
bypassSecurityTrustHtml('<h1>This is DonSanitizer</h1>')
}
}




Monday 11 June 2018

Input Output and forwardRef use for Component Interaction

Component Interaction


This cookbook contains recipes for common component communication scenarios in which two or more components share information.

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

`forwardRef`

import { AppComponent } from '/AppComponent.ts';
@Inject(forwardRef(() => AppComponent))
public _AppComponent: AppComponent)

Pass data from child to parent  with input binding

child =>

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

@Output() filterObj: EventEmitter<Object> = new EventEmitter<Object>();

this.filterObj.emit(filterObj);

parent =>

<app-user (filterData)="filterData($event)"></app-user>

filterData(filterObject) {
console.log('res>>', filterObject);
}

Pass data from parent to child with input binding

child =>

  1. @Input() modelNmae: any;
  2. @Input('master') masterName: string;
  3. @Input() set filter(modelId) { this.getUserList(modelId) }
  4. get filter() { return this.modelId}

parent =>

  1. @Selector <app-user [filter]="filter"></app-user>

Friday 8 June 2018

Dynamic Reactive Forms using FormArray.

To work with a FormArray do the following:
  1. Define the items in the array; that is, FormControls or FormGroups.
  2. Initialize the array with items created from data in the data model.
  3. Add and remove items as the user requires.
In module
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

In Component
import {
FormArray,
FormBuilder,
FormGroup,
FormControl,
Validators }
from '@angular/forms';


export class AddUserComponent implements OnInit {
registrationForm: FormGroup;
formErrors = {};
validationMessages = {};
constructor(private _fb: FormBuilder ) { }

ngOnInit() {
this.setFormErrors();
this.creatForms();
this.getDepartmentDDL();
}
getDepartmentDDL() {
// get list of deparment
this.setFormArray(departmentData)
}

setFormErrors() {
this.formErrors = {
'first_Name': '',
'phone_number': '',
'email': '',
'department': '',
'password': '',
'confirm_password': ''
};
this.validationMessages = {
'first_Name': {
'required': 'First name is required.',
'minlength': 'First name must be at least 4 characters long.',
'maxlength': 'First name cannot be more than 20 characters long.'
},
'phone_number': {
'required': 'Phone number is required.',
'pattern': 'Phone number is invalid.',
'maxlength': 'Phone number cannot be more than 20 number long.'
},
'email': {
'required': 'E-mail is required.',
'email': 'E-mail is invalid.',
'maxlength': 'E-mail cannot be more than 100 characters long.'
},
'password': {
'required': 'Password is required.',
'minlength': 'Password must be at least 4 characters long.',
'maxlength': 'Password cannot be more than 35 characters long.'
},
'confirm_password': {
'required': 'Confirm password is required.',
'invalid': 'Password do not match!'
}
};
}
creatForms() {
this.registrationForm = this._fb.group({
first_Name: [this.user.firstname, [Validators.required,
Validators.minLength(4), Validators.maxLength(20)]],
phone_number: ['', [Validators.required,
Validators.pattern('[0-9\+\-\]+'), Validators.maxLength(20)]],
email: [{ value: this.user.email, disabled: this.isEdit },
[Validators.required, Validators.email, Validators.maxLength(100)]],
password: [this.user.password, this.passwordValidator],
confirm_password: [this.user.password, this.cnfPasswordValidator],
department: this._fb.array([]),
});
this.registrationForm.valueChanges.subscribe(data => this.onFormChanged(data));
}
setFormArray(departmentData) {
const arrayItem = departmentData.map(item => {
const obj = Object.assign({}, item);
obj.selectedArr = '';
return this._fb.group(obj)
});
const roleItems = this._fb.array(arrayItem);
this.registrationForm.setControl(department, roleItems);
}
passwordconfirmation(c: AbstractControl): any {
if (!c.parent || !c) { return; }
const pwd = c.parent.get('password');
const cpwd = c.parent.get('confirm_password')

if (!pwd.value || !cpwd.value) { return; }
if (pwd.value !== cpwd.value) {
return { invalid: true };
}
}
clearConfirmPass() {
this.registrationForm.controls['confirm_password'].setValue(null)
}
onFormChanged(data?: any) {
if (!this.registrationForm) { return; }
const form = this.registrationForm;
// tslint:disable-next-line:forin
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
// tslint:disable-next-line:forin
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}

onClickSave() {
const newUser = {};
newUser['firstname'] = this.registrationForm.value['first_Name'];
newUser['Phone'] = this.registrationForm.value['phone_number'];
newUser['email'] = this.registrationForm.value['email'];
newUser['department'] = this.getDepartmentArr();
}
getDepartmentArr() {
const selectedDepartmentArr = [];
this.registrationForm.value.department.map(item => {
if (item.selectedArr) {
selectedDepartmentArr.push({ sfdcId: item.id, Name: item.Name,
status: item.selectedArr })
}
})
return selectedDepartmentArr;
}
}



In HTML


<form #userForm="ngForm" [formGroup]="registrationForm"
(ngSubmit)="onClickSave()" class="form-material" name='userForm'>
<div class="row m-t-10">
<div class="col-6">
<span>First Name
<span class="text-danger">*</span>
</span>
<input type="text" formControlName="first_Name" name="first_Name"
class="form-control">
<small *ngIf="formErrors.first_Name"
class="help-block text-danger">{{ formErrors.first_Name }}</small>
</div>
</div>
<div class="row m-t-10">
<div class="col-6">
<span>Phone
<span class="text-danger">*</span>
</span>
<input formControlName="phone_number" type="text" class="form-control">
<small *ngIf="formErrors.phone_number"
class="help-block text-danger">{{ formErrors.phone_number }}</small>
</div>
<div class="col-6">
<span>Email
<span class="text-danger">*</span>
</span>
<input formControlName="email" type="text" class="form-control">
<small *ngIf="formErrors.email"
class="help-block text-danger">{{ formErrors.email }}</small>
</div>
</div>

<div formArrayName="department" class="border-t vertical-scroll-user">
<table>
<tr class="m-t-5" *ngFor="let role of department; let i=index"
[formGroupName]="i">
<td>
<span>{{i+1}}.</span>
<span>{{role.Name}}</span>
<span class="text-danger">*</span>
</td>
<td>
<input type="radio" id="{{'active-' + i}}" value="1"
formControlName="selectedArr" class="radio-col-light-blue">
<label for="{{'active-' + i}}">Active</label>
</td>
</tr>
</table>
</div>
</form>









Saturday 26 May 2018

The DevOps lifecycle - it's all about "continuous"

Continuous Integration (CI), Continuous Testing (CT), and Continuous Delivery (CD) are the significant part of DevOps culture. CI includes automating builds, unit tests, and packaging processes while CD is concerned with the application delivery pipeline across different environments. CI and CD accelerate the application development process through automation across different phases, such as build, test, and code analysis, and enable users to achieve end-to-end automation in the application delivery lifecycle:





Thursday 24 May 2018

Handling 401 Unauthorized using interceptor in Angular 4

In the catch, we can handle any and all errors that occur, of primary interest to this example is the 401 Unauthorized error   https://angular.io/api/common/http/HttpInterceptor.
Create a service 
Ex=> Service name is AuthorizationService

import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response,
Http, RequestOptionsArgs, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AuthService } from './authentication.service';
import { UsersApi, LoopBackAuth } from '../sdk';
import { Router } from '@angular/router';
import { AppStateService } from './app-state.service';

@Injectable()
export class AuthorizationService extends Http {

constructor(backend: XHRBackend, defaultOptions: RequestOptions,
private router: Router, private auth: LoopBackAuth) {
super(backend, defaultOptions);
}

request(url:string | Request, options?:RequestOptionsArgs):Observable<Response> {
// do whatever like set custom request headers
return super.request(url, options).catch(this.catchErrors());
}

private catchErrors() {
return (res: Response) => {
if (res.status === 401) {
this.auth.clear();
localStorage.clear();
this.router.navigate(['/login']);
}
return Observable.throw(res);
};
}
}

Use this service in Application App module like this.

import { Http, XHRBackend, RequestOptions } from '@angular/http';
import { RouterModule, Router } from '@angular/router';
import { LoopBackAuth } from './../shared/sdk/services/core/auth.service';
import { AuthorizationService } from '../authorization.service';

providers: [
{
provide: Http,
useFactory: (backend: XHRBackend, options: RequestOptions,
router: Router, auth: LoopBackAuth) => {
return new AuthorizationService(backend, options, router, auth);
},
deps: [XHRBackend, RequestOptions, Router, LoopBackAuth]
}
]























Thursday 29 March 2018

Angular Comma Pipe return comma seprated

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'comma'
})
export class CommaPipe implements PipeTransform {

transform(value: any, args?: any): any {
if (value) {
return (', ').concat(value)
} else {
return value;
}
}

}

Angular count car pipe apply in string.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'countChar',
pure: false
})
export class CountCarPipe implements PipeTransform {

transform(text: string, args: number) {
let maxLength = args || 140
let length = text.length;
return (maxLength - length);
}
}

Angular order pipe apply on object

/*
* Example use
*      Basic Array of single type: *ngFor="#todo of todoService.todos | orderBy : '-'"
*      Multidimensional Array Sort on single column: *ngFor="#todo of todoService.todos | orderBy : ['-status']"
*      Multidimensional Array Sort on multiple columns: *ngFor="#todo of todoService.todos | orderBy : ['status', '-title']"
*/

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'orderByPipe', pure: false })
export class OrderBy implements PipeTransform {

static _orderByComparator(a: any, b: any): number {
if ((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))) {
// Isn't a number so lowercase the string to properly compare
if (a.toLowerCase() < b.toLowerCase()) {
return -1;
}
if (a.toLowerCase() > b.toLowerCase()) {
return 1;
}
} else {
// Parse strings as numbers to compare properly
if (parseFloat(a) < parseFloat(b)) {
return -1;
}
if (parseFloat(a) > parseFloat(b)) {
return 1;
}
}

return 0; // equal each other
}

transform(input: any, [config = '+']): any {

if (!Array.isArray(input)) {
return input;
}

if (!Array.isArray(config) || (Array.isArray(config) && config.length === 1)) {
var propertyToCheck: string = !Array.isArray(config) ? config : config[0];
var desc = propertyToCheck.substr(0, 1) === '-';

// Basic array
if (!propertyToCheck || propertyToCheck === '-' || propertyToCheck === '+') {
return !desc ? input.sort() : input.sort().reverse();
} else {
var property: string = propertyToCheck.substr(0, 1) === '+' || propertyToCheck.substr(0, 1) === '-'
? propertyToCheck.substr(1)
: propertyToCheck;

return input.sort(function (a: any, b: any) {
return !desc
? OrderBy._orderByComparator(a[property], b[property])
: -OrderBy._orderByComparator(a[property], b[property]);
});
}
} else {
// Loop over property of the array in order and sort
return input.sort(function (a: any, b: any) {
for (var i: number = 0; i < config.length; i++) {
var desc = config[i].substr(0, 1) == '-';
var property = config[i].substr(0, 1) == '+' || config[i].substr(0, 1) == '-'
? config[i].substr(1)
: config[i];

var comparison = !desc
? OrderBy._orderByComparator(a[property], b[property])
: -OrderBy._orderByComparator(a[property], b[property]);

// Don't return 0 yet in case of needing to sort by next property
if (comparison !== 0) {
return comparison;
}
}

return 0; // equal each other
});
}
}
}


Use of this pipe.

Data = new OrderBy().transform(Data, ['columnName']);

Angular unique pipe apply any object

import { element } from 'protractor';
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: "unique",
pure: false
})
export class UniquePipe implements PipeTransform {
transform(value: any, level0?: any, level1?: any, level2?: any): any {
let f = [];
if (!Array.isArray(value)) return;
f = value.filter((n: any) => {
if (!n[level0]) return;
if (level1 == null && level2 == null) {
if (n[level0] === 0 || n[level0]) {
return f.indexOf(n[level0]) === -1 && f.push(n[level0]);
}
} else if (level2 == null) {
if (n[level0][level1] === 0 || n[level0][level1]) {
return (
f.indexOf(n[level0][level1]) === -1 && f.push(n[level0][level1])
);
}
} else {
if (n[level0][level1][level2] === 0 || n[level0][level1][level2]) {
return (
f.indexOf(n[level0][level1][level2]) === -1 &&
f.push(n[level0][level1][level2])
);
}
}
});
return f;
}
}

Angular filter Pipe to Dynamically Filter results

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'filter',
pure: false
})
export class FilterPipe implements PipeTransform {

transform(value: any, property: any, propertyValue: any): any {
let f = [];
if (!Array.isArray(value)) return value;
if (propertyValue == 'All') return value;
f = value.filter((n: any) => {
if (!n[property]) return ;
if (n[property] === propertyValue) {
return f.push(n[property])
}
})
return f;
}

}

Angular File Icon Pipe/Filter. Show file icon on behalf of file extention

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'fileicon'
})
export class FileiconPipe implements PipeTransform {
transform(fileMeta: any, fixedIcon: any): any {
if (this.isImage(fileMeta)) {
return 'mdi mdi-camera';
} else if (fixedIcon) {
return 'fa fa-download';
} else {
return this.getFileIcon(fileMeta.name);
}
}

/**
* return true if file is of image type
*/
isImage(file: File): boolean {
return /^image\//.test(file.type);
}

/**
* return file icon based on file name
*/
getFileIcon(filename): string {
let icon = 'mdi mdi-file'; // default Icon;
const ext = /^.+\.([^.]+)$/.exec(filename);
const fileExt = ext == null ? ' ' : ext[1];
if (fileExt === 'pdf') {
icon = 'mdi mdi-file-pdf';
} else if (fileExt === 'xlsx' || fileExt === 'xls' || fileExt === 'csv') {
icon = 'mdi mdi-file-excel';
} else if (fileExt === 'sql' || fileExt === 'txt' || fileExt === 'doc' || fileExt === 'docx' || fileExt === 'text') {
icon = 'mdi mdi-file-document';
} else if (fileExt === 'download') {
icon = 'mdi mdi-download ';
}
return icon;
}

}