Angular Titbits: Concepts that make angular unique

These are intermediate to advanced level concepts as a pre-understanding of angular is needed

Real-life scenarios for using every concept mentioned below is included

1.       Custom Directive (Custom HTML elements!)

Directives are angular syntax for HTML elements.

3 Types:

Scenario for Attribute directive: To stop the user from copy pasting to an input field

@Directive({ name: ‘[preventCopyPaste]’ })

@HostListener(‘paste’, [‘$event’]) blockPaste(event) { event.preventDefault() }

 Use it in any input box: Confirm Email ID <input preventCopyPaste type=”text”>

Note: Selector should be in square braces (selector: [preventCopyPaste] ). Use HostBinding and HostListener

 

2.       Custom Filter

Note: for parameterized filter/Pipe, transform(texVal, paramVal), parameters start from 2nd argument ( {{title | prepend: 'PCBA') }}

Pure Filter: Run the filter only for changes to its input values.

Impure Filter: Run the filter for any change in component. Whenever change detection is executed in the whole component

 

3.       @ViewChild(), @ViewChildren()

Used to refer to a templateRef variable or to refer directly to a component to access its properties.

If using templateRefVariable, use single quotes. If calling a component and referencing it, no quotes

·         Template Ref

 @ViewChild('myRefVar') rf : Elementref; (this.rf.nativeElement.style.color = "green" )

·         Child Component

@ViewChild(myGridCmp) g: myGridCmp; (later you can use any properties/methods of this child component)

@ViewChildren: If referencing more than 1.

Has to be of type QueryList<any> (for element ref var or <componentName> if referencing component)

Ex: @ViewChildren('viewChildrentest') vc : QueryList<any>

console.log(this.vc.toArray()) //lists all the elemets in array format. Inside a map/for loop it can be handled same as @ViewChild()

 

4.       @ContentChild(), @ContentChildren()

Content Projection:

Content projection allows you to insert a shadow DOM in your component. To put it simply, if you want to insert HTML elements or other components in a component, then you do that using concept of content projection. In Angular, you achieve content projection using < ng-content >< /ng-content >.  You can make reusable components and scalable application by right use of content projection.

@ContentChild() : For referencing a local element in a component, #eleRef is used. To refer to an element that in inside another component from a component containing '<ng-content>', you can @ContentChild() use the same #eleRef by using @ContentChild() in the other element.

@ContentChild()  is used for getting access to the ng-content HTML template

EX: @Component({

  selector: 'my-content',

  template: `<div><ng-content></ng-content></div>`

})

export class MyContentComponent {

  @ContentChild('myContentRef') myref: ElementRef;

  @ContentChild('testRef') testref: ElementRef; //DOES NOT WORK! as it is not inside <ng-content>

  ngAfterContentInit() {

    console.log(this.myref);

    console.log(this.testref); //DOES not work

  }

}

 

Usage in other component:

@Component({

  selector: 'hello',

  template: `<h1>Hello <my-content> <div #myContentRef>My content test</div></my-content></h1>

  <p #testRef>Test ref</p>`

  })

 

Child component contains '<ng-content>'. @ContentChild() comes here in the child component. In the parent, wrap the content of <ng-content> inside any HTML tag so that it can be referenced in child's @ContentChild()

-Use select="projection1" for projection of different contents.

 

5.       @HostBinding(), @HostListener()

HostBinding: @HostBinding('attr.role')/  @HostBinding('style.color') fontCol = 'red';

HostListener: @HostListener('paste', [$event]) blockpaste(e: KeyboardEvent) { e.preventDefault(); }

 

6.       Auth Guard

(canActivate) To validate if a particular route link is accessible for the given user/session etc

@Injectable()

export class AuthGuard implements CanActivate {

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

    if (!localStorage.getItem('isLoggedIn')) {

      return confirm('Are you sure you want to navigate?');

    }

    return true;

  }

}

 

7.       Confirm Guard

(canDeactivate) To provide a confirm box before navigating from a form that was not submitted but filled (dirty)

export interface FormComponent {

    myForm: FormGroup;

  }

 

@Injectable()

export class AuthGuardConfirmation implements CanDeactivate<FormComponent> {

    canDeactivate(component: FormComponent) {

        if (component.myForm.dirty) {

        return window.confirm('Are you sure you want to leave Song Details?');

        }

        return true;

    }

}

 

8.       Activated Route snapshot, Activated Route subscribe

ActivatedRoute (snapshot) : one time use. Ex when component loads. (this.IDselected = this._ActivatedRoute.snapshot.params.id;)

ActivatedRoute (subscribe) : Ex when calling the same route of the component with change in parameter, you will get the updated param each time route is changed

Ex:

this._ActivatedRoute.params.subscribe(page => console.log(page))

previous() {

    this.IDselected = this.IDselected -1;

    this._router.navigate(['diamond',this.IDselected])

  }

 

Child Route: When you want routing to happen only from a particular route. Ex, once routed to a an URL like '/department/1' , department contact component routing can only/ happen once known which department is selected (here, 1) 'department/1/contact'.

Just add an additional object in existing routing config for that route

{

        path: 'department/:id',

        component: departmentDetails

        children: [

                        {path: 'contact', component: contactComponent}

        ]

}

And while calling this route from department,

this.router.navigate('[contact]', relativeTo: this._route)

 

9.       Trigger manual change detection

 

10.   Custom form validation

Write a function that takes form control as input parameter, return either an object if there is an error or return null so that the control is in valid form. If invalid, the error object will appear in "error" object of the form control

Ex: myForm = this._formBuilder.group({

        userName: ['', this.myCustomValidator]

        })

myCustomValidator(control) {

        if(!control.value.includes("K")) {

                        { "KNotFound": "No k is found in the userName" }

                        }

        return null

        }

Comments

Popular posts from this blog

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

React & State Management: All Concepts

React: Communication between components