Table of Contents
Angular Interview Questions
1. What are declarations, imports and providers in angular module?
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { StudentComponent } from './student/student.component'; @NgModule({ declarations: [ AppComponent, StudentComponent, ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
declarations is for things you’ll use in your templates : mainly components (~ views : the classes displaying data), but also directives and pipes
we can import other modules by listing them in the imports array The root module in the case of web applications imports the BrowserModule, which for example provides Browser specific renderers, and installs core directives like ngIf, ngFor, etc.
providers is for services (~ models : the classes getting and handling data). Its used to register a service with the root injector we use providers property of @ngModuledecorator and to register a service with the injector at a component level use providers property of @Component decorator.
2. Write a component with inbuilt css styles.
import { Component } from '@angular/core'; @Component({ selector: 'my-employee', templateUrl: 'app/employee/employee.component.html', styles: ['table { color: #369; font-family: Arial, Helvetica, sans-serif; font-size: large; border-collapse: collapse;}', 'td {border: 1px solid black; }'] }) export class EmployeeComponent { firstName: string = 'Tom'; lastName: string = 'Hopkins'; gender: string = 'Male'; age: number = 20; }
3. How to do data binding in Angular?
There are 2 ways to do the data binding in angular
1. One way binding with Interpolation and property binding
2. Two way binding with ngModal
4. How to do data binding from component to view template in angular?
5. What is the use of interpolation and property binding?
6. What is difference between interpolation and property binding
Interpolation in Angular
To display read-only data on a view template we use one-way data binding technique interpolation. With interpolation, we place the component property name in the view template, enclosed in double curly braces: {{propertyName}}.
We can also call class methods using interpolation as shown below.
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<div> <h1>{{pageHeader}}</h1> <img src='{{imagePath}}'/> </div>` }) export class AppComponent { pageHeader: string = 'Employee Details'; imagePath: string = 'http://pragimtech.com/images/logo.jpg'; }
Interpolation with method
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<div> <h1>{{'Full Name = ' + getFullName()}}</h1> </div>` }) export class AppComponent { firstName: string = 'Tom'; lastName: string = 'Hopkins'; getFullName(): string { return this.firstName + ' ' + this.lastName; } }
Interpolation vs property binding in Angular
Interpolation example in angular
<button disabled='{{isDisabled}}'>Click Me</button>
Property binding example in angular
<button [disabled]='{{isDisabled}}'>Click Me</button>
If you notice the above 2 examples, it looks like we are binding to the Button’s disabled attribute. This is not true. We are actually binding to the disabled property of the button object. Angular data-binding is all about binding to DOM object properties and not HTML element attributes.
What is the difference between HTML element attribute and DOM property
1. Attributes are defined by HTML, where as properties are defined by the DOM.
2. Attributes initialize DOM properties. Once the initialization complete, the attributes job is done.
3. Property values can change, where as attribute values can’t.
Let’s prove this point – Property values change, but the attribute values don’t with an example.
In the example below, we have set the value attribute of the input element to Tom.
<input id=’inputId’ type=’text’ value=’Tom’>
At this point, run the web page and in the textbox you will see ‘Tom’ as the value.
Launch the browser developer tools.
On the ‘Console’ tab, use the getattribute() method and value property of the input element to get the attribute and property values. Notice at the moment both have the value ‘Tom’
Change the value in the textbox to Mary.
Notice now, when we query for the attribute and property values, the attribute value is still Tom but the property value is Mary. So this proves the point – Property values change, whereas attribute values.
So it is important to keep in mind that,
1. Attribute initialize DOM property. Once the initialization complete the attribute job is done.
2. Property values can change whereas attribute value can’t.
7. What is 2 Way data binding in Angular?
import { FormsModule } from '@angular/forms';
imports: [BrowserModule, FormsModule]
Name : <input [value]='name' (input)='name = $event.target.value'> You Entered : <input [(ngModel)]='name'>
Whats special about 2 way binding sysntaxt in angular?
The square brackets on the outside are for property binding
8. What is Pipe in Angular?
A pipe takes in data as input and transforms it to a desired output.
<td>{{employee.code | uppercase}}</td> <td>{{employee.dateOfBirth | date:'fullDate' | uppercase }}</td> <td>{{employee.dateOfBirth | date:'dd/MM/y'}}</td> <td>{{employee.annualSalary | currency:'USD':true:'1.3-3'}}</td>
9. How to create custom pipe in Angular?
Step 1 : Define Pipe which implements the PipeTransform interface
@Pipe({ name: 'employeeTitle' pure : false }) export class EmployeeTitlePipe implements PipeTransform { transform(value: string, gender: string): string { if (gender.toLowerCase() == "male") return "Mr." + value; else return "Miss." + value; } }
Step 2 : Register “EmployeeTitlePipe” in the angular module where we need it. In our case we need it in the root module. So in app.module.ts file, import the EmployeeTitlePipe and include it in the “declarations” array of NgModule decorator
import { EmployeeTitlePipe } from './employee/employeeTitle.pipe' @NgModule({ imports: [BrowserModule], declarations: [AppComponent, EmployeeComponent, EmployeeListComponent, EmployeeTitlePipe], bootstrap: [AppComponent] }) export class AppModule { }
Step 3 : In “employeeList.component.html” use the “EmployeeTitlePipe” as shown below. Notice we are passing employee gender as an argument for the gender parameter of our custom pipe. Employee name gets passed automatically.
<tr *ngFor='let employee of employees;'> <td>{{employee.code}}</td> <td>{{employee.name | employeeTitle:employee.gender}}</td> <td>{{employee.gender}}</td> <td>{{employee.annualSalary}}</td> <td>{{employee.dateOfBirth}}</td>
10. What are Types of Pipe in Angular?
So the key takeaway here is that even if the input doesn’t change the impure function can produce different output. It means that we cannot use the input value to determine if the output will change.
1. Pure pipe in angular
– input parameters value determine the output so if input parameters don’t change the output doesn’t change
– can be shared across many usages without affecting the output result
– A pure pipe is only called when Angular detects a change in the value or the parameters passed to a pipe.
2. Impure pipe in angular
• cannot use the input value to determine if the output will change
• cannot be shared because the internal state can be affected from outside
• An impure pipe is called for every change detection cycle no matter whether the value or parameters changes.
11. How to send data from parent component to child component?
@Input to be used where we want to pass the variable value from parent component to nested component.
Define the parameters uin nested component
import { Component, Input } from '@angular/core'; @Component({ selector: 'employee-count', templateUrl: 'app/employee/employeeCount.component.html', styleUrls: ['app/employee/employeeCount.component.css'] }) export class EmployeeCountComponent { @Input() all: number; @Input() male: number; @Input() female: number; }
Write below methods in parent component to get the count
getTotalEmployeesCount(): number { return this.employees.length; } getMaleEmployeesCount(): number { return this.employees.filter(e => e.gender === 'Male').length; } getFemaleEmployeesCount(): number { return this.employees.filter(e => e.gender === 'Female').length; }
Define the variable name and its associated method to get the count in parent component.
<employee-count [all]="getTotalEmployeesCount()" [male]="getMaleEmployeesCount()" [female]="getFemaleEmployeesCount()"> </employee-count>
12. How to Access Child Component from Parent?
we can access child component from parent component with 3 different ways.1. Parent uses local variable to access the Child in Template
2. Parent uses a @ViewChild() to get reference to the Child
3. @Output Property
13. How to Access Child Component from Parent with id?
export class ChildComponent { count = 0; increment() { this.count++; } decrement() { this.count--; } }
Parent HTML
<button (click)="child.increment()">Increment</button> <button (click)="child.decrement()">decrement</button> <child-component #child></child-component>
We have created a local variable, #child, on the tag <child-component>. The “child” is called template reference variable, which now represents the child component
14. How to Access Child Component from Parent with @ViewChild()?
The @ViewChild decorator takes the name of the component/directive as its input. It is then used to decorate a property. The Angular then injects the reference of the component to the Property
Parent HTML :
<p> current count is {{child.count}} </p> <button (click)="increment()">Increment</button> <button (click)="decrement()">decrement</button> <child-component></child-component>`
Parent Component
export class AppComponent { title = 'Parent calls an @ViewChild()'; @ViewChild(ChildComponent) child: ChildComponent; //using child component reference to call its methods increment() { this.child.increment(); } decrement() { this.child.decrement(); }
15. How to Access Child Component from Parent with @Output Property?
1. Create EventEmitter in child component
@Output() countRadioButtonEventEmitter: EventEmitter<string> = new EventEmitter<string>();
2. Write a method to emit the value to parent component
onRadioButtonSelectionChnage() { console.log('selectedRadioButton : ' + this.selectedRadioButton); this.countRadioButtonEventEmitter.emit(this.selectedRadioButton); }
3. Define the onchnage handler in child component
<input type="radio" name="options" value="All" [(ngModel)]="selectedRadioButton" (change)="onRadioButtonSelectionChnage()"/> <span class="radioClass">{{"All(" + all + ")"}}</span>
4. Define he EventEmitter variable name in parent component with method to handle the new value
<app-employeecounter [all]="getAllEmployee()" [male]="getMaleEmployee()" [female]="getFemaleEmployee()" (countRadioButtonEventEmitter)="onEmployeeCountRadioButtonChange($event)"> </app-employeecounter>
5. The return value of EventEmitter will be catched by JS function as below who have the param same as EventEmmiter.
onEmployeeCountRadioButtonChange(selectedRadioButtonValue: string): void { this.selectedEmployeeCountRadioButton = selectedRadioButtonValue; }
16. What are the Types of Directives in Angular?
Angular 2 categorizes directives into 3 parts:
1. Directives with templates known as Components
2. Directives that creates and destroys DOM elements known as Structural Directives
3. Directives that manipulate DOM by changing behavior and appearance known as Attribute Directives
Component Directive in Angular
Decorator that marks a class as an Angular component and provides configuration metadata that determines how the component should be processed, instantiated, and used at runtime.
@Component({ // this is a declarator which starts with @ sign. The component word marked in bold needs to be the same. selector: 'app-new-cmp', // templateUrl: './new-cmp.component.html', // reference to the html file created in the new component. styleUrls: ['./new-cmp.component.css'] // reference to the style file. }) export class NewCmpComponent implements OnInit { constructor() { } ngOnInit() {} }
Attribute Directives in Angular
They are used to manipulate the DOM in all kinds of different ways except creating or destroying them. change the appearance or behavior of an element, component, or other directive. Dynamically changing the behavior of a component based on a changing property.
<p [hidden]="shouldHide">Directives are awesome</p>
Structural Directives
Structural directives are not DOM-friendly in the sense that they create, destroy, or re-create DOM elements based on certain conditions.
This is a huge difference from what hidden attribute directive does. This is because hidden retains the DOM element but hides it from the user, whereas structural directives like *ngIf destroy the elements.
17. How to create Custom Attribute Directive in Angular?
import { Directive, ElementRef, Renderer } from '@angular/core'; // Directive decorator @Directive({ selector: '[myHidden]' }) // Directive class export class HiddenDirective { constructor(el: ElementRef, renderer: Renderer) { // Use renderer to render the element with styles renderer.setElementStyle(el.nativeElement, 'display', 'none'); } @HostListener('mouseover') onHover() { window.alert("hover"); } }
18. How to create Custom Structure Directive in Angular?
19. How *ngIf internally works?
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[myNgIf]'}) export class MyNgIfDirective { constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { } @Input() set myNgIf(condition: boolean) { if (condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } }
<div *myNgIf=”person”>{{person.name}}</div>
TemplateRef — As the name suggest the TemplateRef is just a reference to the template.
ViewContainerRef is responsible for putting the code inside the html tag
20. How to write Constructor in Angular or Typescript?
export class Employee { private firstName: string; private lastName: string; constructor(firstName: string, lastName: string) { this.firstName = firstName; this.lastName = lastName; } }
We can rewrite the above code using shorthand syntax as shown below. In both the cases the generated JavaScript code is the same.
export class Employee { constructor(private firstName: string, private lastName: string) { } }
21. What is @Injectable in Angular?
@Injectable() marks a class as available to an injector for instantiation. An injector reports an error when trying to instantiate a class that is not marked as @Injectable().
Injectors are also responsible for instantiating components. At the run-time the injectors can read class metadata in the JavaScript code and use the constructor parameter type information to determine what things to inject.
22. How to use Dependency Injection in Angular?
The basics Steps of Dependency injection,
1. A class with @Injectable() to tell angular 2 that it’s to be injected “UserService”.
2. A class with a constructor that accepts a type to be injected.
Example, UserService marked as @Injectable as,
import {Injectable, bind} from 'angular2/core'; import {Http} from 'angular2/http'; @Injectable() /* This is #Step 1 */ export class UserService { constructor(http: URL /* This is #Step 2 */ ) { this.http = URL; } }
23. How to implement forms in Angular?
What is difference in between Template driven form and
There are 2 ways through wich we can create form
1. Template-driven
2. Model-driven form or Reactive form
24. What is difference between Template-Driven and Reactive Forms in Angular?
What is Template-driven form in Angular?
In this method, we build the form object and assign the validations in HTML. Here we are passing the form object into the submit method.
<form (ngSubmit)="onSubmit(carForm.value)" #carForm="ngForm"> <div class="form-group"> <label class="col-xs-4 control-label" for="greenCarName" >Green car name : </label> <div class="col-xs-8"> <input type="text" style="width: 300px" class="form-control" required [(ngModel)]="myCar.greenCarName" // 2 way binding the input field to the object in Component ngControl="greenCarName" #greenCarName="ngForm" required minlength="10"> <div [hidden]="greenCarName.valid || greenCarName.pristine" class="alert alert-danger"> The Name of green car is required ! </div> </div> </div>
Below are the built in validations for template
• required: There must be a value
• minlength: The number of characters must be more than the value of the attribute.
• maxlength: The number of characters must not exceed the value of the attribute.
• pattern: The value must match the pattern.
// Our form component @Component({ selector: 'angular-typescript-form', templateUrl: 'app/angular-typescript-form.component.html', directives: [CORE_DIRECTIVES, FORM_DIRECTIVES] }) export class FormExample { myCar = new GreenCar(1,'BMW Serie 1','Red',2); // this is our green car instance //the constructor is a good place for initialization (not big things) constructor(){ console.log("Form Component Start"); } submitted = false; //form not submited : default data: string; //this variable contains our data //Show data after form submit and set submitted to true onSubmit(data) { this.submitted = true; this.data = JSON.stringify(data, null, 2); // getting data into string variable console.log(this.data); } }
In this approach we need to define the validation logic into the html file and component file will not hold the configurations.
What is Model-driven forms in Angular or Re active forms in Angular?
In Model driven forms or Reactive forms in Angular, we define all the validation logic in component and build the form object in component instead of HTML.
HTML
<form [ngFormModel]="studentForm" class="form-horizontal" id='myForm' role="form"> <div class="col-md-7"> Name: <input ngControl="name" #name="ngForm" [(ngModel)]="student.name" type="text" placeholder="Name" class="form-control"> <span [hidden]="name.valid"><b>Required</b></span> </div> <div class="col-md-7"> Password: <input ngControl="password" #password="ngForm" [(ngModel)]="student.password" type="text" id="password" placeholder="password" class="form-control"> // ngControl is a class that binds a Control object to an element. In this case, the element that it's applied to is an input <span [hidden]="!password.control.hasError('required')"><b>Required</b></span> <span [hidden]="!password.control.hasError('startsWithNumber')"><b>Must start with number</b></span> </div> </form>
Component
import {Component} from 'angular2/core'; import {CORE_DIRECTIVES, NgClass, FORM_DIRECTIVES, Control, ControlGroup, FormBuilder, Validators} from 'angular2/common'; class Student { name:string; password:string; } interface ValidationResult { [key:string]:boolean; } class PasswordValidator { static startsWithNumber(control: Control): ValidationResult { if ( control.value && control.value.length > 0){ if (isNaN(control.value[0])) return { 'startsWithNumber': true }; } return null; } } @Component({ selector: 'my-app', templateUrl: 'mytemplate.html', directives: [CORE_DIRECTIVES, FORM_DIRECTIVES] }) export class AppComponent { student:Student; studentForm: ControlGroup; constructor(fb: FormBuilder){ this.student = new Student(); this.studentForm = fb.group({ 'name': new Control(this.student.name, Validators.required), // with the help of Control we can define the validation in component only that we used to define in HTML for ngForm 'password': new Control(this.student.password, Validators.compose([Validators.required,PasswordValidator.startsWithNumber])), // adding cutom validation or more than 1 validation }); }
25. What are Lifecycle Hooks in Angular?
1. constructor
This is invoked when Angular creates a component or directive by calling new on the class.
ngOnChanges
Invoked every time there is a change in one of th input properties of the component.
ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); console.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); } }
2. ngOnInit
Invoked when given component has been initialized. This hook is only called once after the first ngOnChanges. Note that ngOnChanges hook is fired before ngOnInit. Which means all the input properties are available to use when the ngOnInit is hook is called. This hook is fired only once. This hook is fired before any of the child directive properties are initialized.
3. ngDoCheck
Invoked when the change detector of the given component is invoked. It allows us to implement our own change detection algorithm for the given component. Angular calls this hook very frequently. This hook is called after every change detection cycle no matter where the change has occurred. This is used when we want to perform the checking of object which is not detected in ngOnChnage event.
If the model reference doesn’t change, but some property of the Input model(object) changes, you may implement the ngDoCheck lifecycle hook to construct your change detection logic manually.
3.1 KeyValueDiffers – It is used when we want to detect the change in an onbject property.
import { DoCheck, KeyValueDiffers } from '@angular/core'; @Component({...}) class ChildComponent implements DoCheck { @Input() person: any; differ: any; constructor(private differs: KeyValueDiffers) { this.differ = differs.find({}).create(null); //this will return the IterableDifferFactory object for all objects available in this child component } ngDoCheck() { var changes = this.differ.diff(this.person); if(changes) { console.log('changes detected'); changes.forEachChangedItem(r => console.log('changed ', r.currentValue)); changes.forEachAddedItem(r => console.log('added ' + r.currentValue)); changes.forEachRemovedItem(r => console.log('removed ' + r.currentValue)); } else { console.log('nothing changed'); } } }
3.2. IterableDiffers – if you get a list / array as @Input, you can use IterableDiffers
export class SomeComponent { constructor(differs: IterableDiffers) { this.differ = differs.find([]).create(null); } @Input() data: any; ngDoCheck() { console.log('ngDoCheck'); var changes = this.differ.diff(this.data.datasets); console.log('changes = '+changes); if (changes) {// && this.initialized) { //doreload changes.forEachAddedItem((record) => { console.log('added ' + record.item); }); changes.forEachRemovedItem((record) => { console.log('removed ' + record.item); }); } } }
4. ngOnDestroy
This method will be invoked just before Angular destroys the component.
Use this hook to unsubscribe observables and detach event handlers to avoid memory leaks.
Hooks for the components children
1. ngAfterContentInit
Invoked after Angular performs any content projection into the components view (see the previous lecture on Content Projection for more info).
2. ngAfterContentChecked
Invoked each time the content of the given component has been checked by the change detection mechanism of Angular.
3. ngAfterViewInit
Invoked when the component’s view has been fully initialized.
4. ngAfterViewChecked
Invoked each time the view of the given component has been checked by the change detection mechanism of Angular.