Angular logo

Angular

Click on the star icon to add the question to your favorites. Found an issue? Let us know.

1. Explain how custom elements works internally?

Below are the steps in an order about custom elements functionality,

  1. App registers custom element with browser: Use the createCustomElement() function to convert a component into a class that can be registered with the browser as a custom element.
  2. App adds custom element to DOM: Add custom element just like a built-in HTML element directly into the DOM.
  3. Browser instantiate component based class: Browser creates an instance of the registered class and adds it to the DOM.
  4. Instance provides content with data binding and change detection: The content with in template is rendered using the component and DOM data.
2. How to transfer components to custom elements?

Transforming components to custom elements involves two major steps,

  1. Build custom element class: Angular provides the createCustomElement() function for converting an Angular component (along with its dependencies) to a custom element. The conversion process implements NgElementConstructor interface, and creates a constructor class which is used to produce a self-bootstrapping instance of Angular component.
  2. Register element class with browser: It uses customElements.define() JS function, to register the configured constructor and its associated custom-element tag with the browser's CustomElementRegistry. When the browser encounters the tag for the registered element, it uses the constructor to create a custom-element instance.
3. What are the mapping rules between Angular component and custom element?

The Component properties and logic maps directly into HTML attributes and the browser's event system. Let us describe them in two steps,

  1. The createCustomElement() API parses the component input properties with corresponding attributes for the custom element. For example, component @Input('myInputProp') converted as custom element attribute my-input-prop.
  2. The Component outputs are dispatched as HTML Custom Events, with the name of the custom event matching the output name. For example, component @Output() valueChanged = new EventEmitter() converted as custom element with dispatch event as "valueChanged".
4. How do you define typings for custom elements?

You can use the NgElement and WithProperties types exported from @angular/elements. Let's see how it can be applied by comparing with Angular component.

  1. The simple container with input property would be as below,
    @Component(...)
    class MyContainer {
    @Input() message: string;
    }
  2. After applying types typescript validates input value and their types,
    const container = document.createElement('my-container') as NgElement & WithProperties<{message: string}>;
    container.message = 'Welcome to Angular elements!';
    container.message = true;  // <-- ERROR: TypeScript knows this should be a string.
    container.greet = 'News';  // <-- ERROR: TypeScript knows there is no `greet` property on `container`.
5. What are dynamic components?

Dynamic components are the components in which components location in the application is not defined at build time.i.e, They are not used in any angular template. But the component is instantiated and placed in the application at runtime.

6. What are the various kinds of directives?

There are mainly three kinds of directives,

  1. Components — These are directives with a template.
  2. Structural directives — These directives change the DOM layout by adding and removing DOM elements.
  3. Attribute directives — These directives change the appearance or behavior of an element, component, or another directive.
7. What are the restrictions of metadata?

In Angular, You must write metadata with the following general constraints,

  1. Write expression syntax with in the supported range of javascript features
  2. The compiler can only reference symbols which are exported
  3. Only call the functions supported by the compiler
  4. Decorated and data-bound class members must be public.
8. What are the two phases of AOT?

The AOT compiler works in three phases,

  1. Code Analysis: The compiler records a representation of the source
  2. Code generation: It handles the interpretation as well as places restrictions on what it interprets.
  3. Validation: In this phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
9. Can I use arrow functions in AOT?

No, Arrow functions or lambda functions can’t be used to assign values to the decorator properties. For example, the following snippet is invalid:

@Component({
providers: [{
provide: MyService, useFactory: () => getService()
}]
})

To fix this, it has to be changed as following exported function:

function getService(){
return new MyService();
}
@Component({
providers: [{
provide: MyService, useFactory: getService
}]
})

If you still use arrow function, it generates an error node in place of the function. When the compiler later interprets this node, it reports an error to turn the arrow function into an exported function. Note: From Angular5 onwards, the compiler automatically performs this rewriting while emitting the .js file.

10. What is the purpose of metadata json files?

The metadata.json file can be treated as a diagram of the overall structure of a decorator's metadata, represented as an abstract syntax tree(AST). During the analysis phase, the AOT collector scan the metadata recorded in the Angular decorators and outputs metadata information in .metadata.json files, one per .d.ts file.

11. Can I use any javascript feature for expression syntax in AOT?

No, the AOT collector understands a subset of (or limited) JavaScript features. If an expression uses unsupported syntax, the collector writes an error node to the .metadata.json file. Later point of time, the compiler reports an error if it needs that piece of metadata to generate the application code.

12. What is folding?

The compiler can only resolve references to exported symbols in the metadata. Where as some of the non-exported members are folded while generating the code. i.e Folding is a process in which the collector evaluate an expression during collection and record the result in the .metadata.json instead of the original expression. For example, the compiler couldn't refer selector reference because it is not exported

let selector = 'app-root';
@Component({
selector: selector
})

Will be folded into inline selector

@Component({
selector: 'app-root'
})

Remember that the compiler can’t fold everything. For example, spread operator on arrays, objects created using new keywords and function calls.

13. How do you provide configuration inheritance?

Angular Compiler supports configuration inheritance through extends in the tsconfig.json on angularCompilerOptions. i.e, The configuration from the base file(for example, tsconfig.base.json) are loaded first, then overridden by those in the inheriting config file.

{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
14. How do you specify angular template compiler options?

The angular template compiler options are specified as members of the angularCompilerOptions object in the tsconfig.json file. These options will be specified adjecent to typescript compiler options.

{
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
15. How do you enable binding expression validation?

You can enable binding expression validation explicitly by adding the compiler option fullTemplateTypeCheck in the "angularCompilerOptions" of the project's tsconfig.json. It produces error messages when a type error is detected in a template binding expression. For example, consider the following component:

@Component({
selector: 'my-component',
template: '{{user.contacts.email}}'
})
class MyComponent {
user?: User;
}

This will produce the following error:

my.component.ts.MyComponent.html(1,1): : Property 'contacts' does not exist on type 'User'. Did you mean 'contact'?
16. What is the purpose of any type cast function?

You can disable binding expression type checking using $any() type cast function(by surrounding the expression). In the following example, the error Property contacts does not exist is suppressed by casting user to the any type.

template:
'{{ $any(user).contacts.email }}'

The $any() cast function also works with this to allow access to undeclared members of the component.

template:
'{{ $any(this).contacts.email }}'
17. What is Non null type assertion operator?

You can use the non-null type assertion operator to suppress the Object is possibly 'undefined' error. In the following example, the user and contact properties are always set together, implying that contact is always non-null if user is non-null. The error is suppressed in the example by using contact!.email.

@Component({
selector: 'my-component',
template: '<span *ngIf="user"> {{user.name}} contacted through {{contact!.email}} </span>'
})
class MyComponent {
user?: User;
contact?: Contact;
setData(user: User, contact: Contact) {
this.user = user;
this.contact = contact;
}
}
18. How to inject the dynamic script in angular?

Using DomSanitizer we can inject the dynamic Html,Style,Script,Url.

import { Component, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'my-app',
template: `
<div [innerHtml]="htmlSnippet"></div>
`,
})
export class App {
constructor(protected sanitizer: DomSanitizer) {}
htmlSnippet: string = this.sanitizer.bypassSecurityTrustScript("<script>safeCode()</script>");
}
19. What is Angular Ivy?

Angular Ivy is a new rendering engine for Angular. You can choose to opt in a preview version of Ivy from Angular version 8.

  1. You can enable ivy in a new project by using the --enable-ivy flag with the ng new command
    ng new ivy-demo-app --enable-ivy
  2. You can add it to an existing project by adding enableIvy option in the angularCompilerOptions in your project's tsconfig.app.json.
    {
    "compilerOptions": { ... },
    "angularCompilerOptions": {
    "enableIvy": true
    }
    }
20. What are the features included in ivy preview?

You can expect below features with Ivy preview,

  1. Generated code that is easier to read and debug at runtime
  2. Faster re-build time
  3. Improved payload size
  4. Improved template type checking
21. What is Angular Language Service?

The Angular Language Service is a way to get completions, errors, hints, and navigation inside your Angular templates whether they are external in an HTML file or embedded in annotations/decorators in a string. It has the ability to autodetect that you are opening an Angular file, reads your tsconfig.json file, finds all the templates you have in your application, and then provides all the language services.

22. How do you add web workers in your application?

You can add web worker anywhere in your application. For example, If the file that contains your expensive computation is src/app/app.component.ts, you can add a Web Worker using ng generate web-worker app command which will create src/app/app.worker.ts web worker file. This command will perform below actions,

  1. Configure your project to use Web Workers
  2. Adds app.worker.ts to receive messages
    addEventListener('message', ({ data }) => {
    const response = `worker response to ${data}`;
    postMessage(response);
    });
  3. The component app.component.ts file updated with web worker file
    if (typeof Worker !== 'undefined') {
    // Create a new
    const worker = new Worker('./app.worker', { type: 'module' });
    worker.onmessage = ({ data }) => {
    console.log('page got message: $\{data\}');
    };
    worker.postMessage('hello');
    } else {
    // Web Workers are not supported in this environment.
    }

Note: You may need to refactor your initial scaffolding web worker code for sending messages to and from.

23. What are the limitations with web workers?

You need to remember two important things when using Web Workers in Angular projects,

  1. Some environments or platforms(like @angular/platform-server) used in Server-side Rendering, don't support Web Workers. In this case you need to provide a fallback mechanism to perform the computations to work in this environments.
  2. Running Angular in web worker using @angular/platform-webworker is not yet supported in Angular CLI.
24. What is Angular CLI Builder?

In Angular8, the CLI Builder API is stable and available to developers who want to customize the Angular CLI by adding or modifying commands. For example, you could supply a builder to perform an entirely new task, or to change which third-party tool is used by an existing command.

25. What is a builder?

A builder function ia a function that uses the Architect API to perform a complex process such as "build" or "test". The builder code is defined in an npm package. For example, BrowserBuilder runs a webpack build for a browser target and KarmaBuilder starts the Karma server and runs a webpack build for unit tests.

26. How do you invoke a builder?

The Angular CLI command ng run is used to invoke a builder with a specific target configuration. The workspace configuration file, angular.json, contains default configurations for built-in builders.

27. How do you create app shell in Angular?

An App shell is a way to render a portion of your application via a route at build time. This is useful to first paint of your application that appears quickly because the browser can render static HTML and CSS without the need to initialize JavaScript. You can achieve this using Angular CLI which generates an app shell for running server-side of your app.

ng generate appShell [options] (or)
ng g appShell [options]
28. What are the case types in Angular?

Angular uses capitalization conventions to distinguish the names of various types. Angular follows the list of the below case types.

  1. camelCase : Symbols, properties, methods, pipe names, non-component directive selectors, constants uses lowercase on the first letter of the item. For example, "selectedUser"
  2. UpperCamelCase (or PascalCase): Class names, including classes that define components, interfaces, NgModules, directives, and pipes uses uppercase on the first letter of the item.
  3. dash-case (or "kebab-case"): The descriptive part of file names, component selectors uses dashes between the words. For example, "app-user-list".
  4. UPPER_UNDERSCORE_CASE: All constants uses capital letters connected with underscores. For example, "NUMBER_OF_USERS".
29. What is Bazel tool?

Bazel is a powerful build tool developed and massively used by Google and it can keep track of the dependencies between different packages and build targets. In Angular8, you can build your CLI application with Bazel. Note: The Angular framework itself is built with Bazel.

30. What are the advantages of Bazel tool?

Below are the list of key advantages of Bazel tool,

  1. It creates the possibility of building your back-ends and front-ends with the same tool
  2. The incremental build and tests
  3. It creates the possibility to have remote builds and cache on a build farm.
31. What are the security principles in angular?

Below are the list of security principles in angular,

    1.    You should avoid direct use of the DOM APIs.
    2.  You should enable Content Security Policy (CSP) and configure your web server to return appropriate CSP HTTP headers.
    3.  You should Use the offline template compiler.
    4.  You should Use Server Side XSS protection.
    5.  You should Use DOM Sanitizer.
    6.  You should Preventing CSRF or XSRF attacks. 
  1. What is the reason to deprecate Web Tracing Framework?

    Angular has supported the integration with the Web Tracing Framework (WTF) for the purpose of performance testing. Since it is not well maintained and failed in majority of the applications, the support is deprecated in latest releases.
32. What is schematic

It's a scaffolding library that defines how to generate or transform a programming project by creating, modifying, refactoring, or moving files and code. It defines rules that operate on a virtual file system called a tree.

33. What is rule in Schematics?

In schematics world, it's a function that operates on a file tree to create, delete, or modify files in a specific manner.

34. What are the best practices for security in angular?

Below are the best practices of security in angular,

  1. Use the latest Angular library releases
  2. Don't modify your copy of Angular
  3. Avoid Angular APIs marked in the documentation as “Security Risk.”
35. What is Angular security model for preventing XSS attacks?

Angular treats all values as untrusted by default. i.e, Angular sanitizes and escapes untrusted values When a value is inserted into the DOM from a template, via property, attribute, style, class binding, or interpolation.

36. What are the various security contexts in Angular?

Angular defines the following security contexts for sanitization,

  1. HTML: It is used when interpreting a value as HTML such as binding to innerHtml.
  2. Style: It is used when binding CSS into the style property.
  3. URL: It is used for URL properties such as <a href>.
  4. Resource URL: It is a URL that will be loaded and executed as code such as <script src>.
37. Is safe to use direct DOM API methods in terms of security?

No,the built-in browser DOM APIs or methods don't automatically protect you from security vulnerabilities. In this case it is recommended to use Angular templates instead of directly interacting with DOM. If it is unavoidable then use the built-in Angular sanitization functions.

38. What is DOM sanitizer?

DomSanitizer is used to help preventing Cross Site Scripting Security bugs (XSS) by sanitizing values to be safe to use in the different DOM contexts.

39. How do you support server side XSS protection in Angular application?

The server-side XSS protection is supported in an angular application by using a templating language that automatically escapes values to prevent XSS vulnerabilities on the server. But don't use a templating language to generate Angular templates on the server side which creates a high risk of introducing template-injection vulnerabilities.

40. Does angular prevent http level vulnerabilities?

Angular has built-in support for preventing http level vulnerabilities such as as cross-site request forgery (CSRF or XSRF) and cross-site script inclusion (XSSI). Even though these vulnerabilities need to be mitigated on server-side, Angular provides helpers to make the integration easier on the client side.

  1. HttpClient supports a token mechanism used to prevent XSRF attacks
  2. HttpClient library recognizes the convention of prefixed JSON responses(which non-executable js code with ")]}',\n" characters) and automatically strips the string ")]}',\n" from all responses before further parsing
41. What is TestBed?

TestBed is an api for writing unit tests for Angular applications and it's libraries. Even though We still write our tests in Jasmine and run using Karma, this API provides an easier way to create components, handle injection, test asynchronous behaviour and interact with our application.

42. What is protractor?

Protractor is an end-to-end test framework for Angular and AngularJS applications. It runs tests against your application running in a real browser, interacting with it as a user would.

npm install -g protractor
43. How do you create schematics for libraries?

You can create your own schematic collections to integrate your library with the Angular CLI. These collections are classified as 3 main schematics,

  1. Add schematics: These schematics are used to install library in an Angular workspace using ng add command. For example, @angular/material schematic tells the add command to install and set up Angular Material and theming.
  2. Generate schematics: These schematics are used to modify projects, add configurations and scripts, and scaffold artifacts in library using ng generate command. For example, @angular/material generation schematic supplies generation schematics for the UI components. Let's say the table component is generated using ng generate @angular/material:table .
  3. Update schematics: These schematics are used to update library's dependencies and adjust for breaking changes in a new library release using ng update command. For example, @angular/material update schematic updates material and cdk dependencies using ng update @angular/material command.
44. What is the reason for No provider for HTTP exception?

This exception is due to missing HttpClientModule in your module. You just need to import in module as below,

import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
],
declarations: [ AppComponent ],
bootstrap:    [ AppComponent ]
})
export class AppModule { }
45. Is mandatory to pass static flag for ViewChild?

In Angular 8, the static flag is required for ViewChild. Whereas in Angular9, you no longer need to pass this property. Once you updated to Angular9 using ng update, the migration will remove { static: false } script everywhere.

@ViewChild(ChildDirective) child: ChildDirective; // Angular9 usage
@ViewChild(ChildDirective, { static: false }) child: ChildDirective; //Angular8 usage
46. What is the precedence between pipe and ternary operators?

The pipe operator has a higher precedence than the ternary operator (?:). For example, the expression first ? second : third | fourth is parsed as first ? second : (third | fourth).

47. How do you manually bootstrap an application?

You can use ngDoBootstrap hook for a manual bootstrapping of the application instead of using bootstrap array in @NgModule annotation. This hook is part of DoBootstap interface.

interface DoBootstrap {
ngDoBootstrap(appRef: ApplicationRef): void
}

The module needs to be implement the above interface to use the hook for bootstrapping.

class AppModule implements DoBootstrap {
ngDoBootstrap(appRef: ApplicationRef) {
appRef.bootstrap(AppComponent); // bootstrapped entry component need to be passed
}
}
48. Is it necessary for bootstrapped component to be entry component?

Yes, the bootstrapped component needs to be an entry component. This is because the bootstrapping process is an imperative process.

49. Why is not necessary to use entryComponents array every time?

Most of the time, you don't need to explicity to set entry components in entryComponents array of ngModule decorator. Because angular adds components from both @NgModule.bootstrap and route definitions to entry components automatically.

50. What is the role of ngModule metadata in compilation process?

The @NgModule metadata is used to tell the Angular compiler what components to be compiled for this module and how to link this module with other modules.

51. How does angular finds components, directives and pipes?

The Angular compiler finds a component or directive in a template when it can match the selector of that component or directive in that template. Whereas it finds a pipe if the pipe's name appears within the pipe syntax of the template HTML.

52. What are feature modules?

Feature modules are NgModules, which are used for the purpose of organizing code. The feature module can be created with Angular CLI using the below command in the root directory,

ng generate module MyCustomFeature //

Angular CLI creates a folder called my-custom-feature with a file inside called my-custom-feature.module.ts with the following contents

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class MyCustomFeature { }

Note: The "Module" suffix shouldn't present in the name because the CLI appends it.

53. What are the steps to use declaration elements?

Below are the steps to be followed to use declaration elements.

  1. Create the element(component, directive and pipes) and export it from the file where you wrote it
  2. Import it into the appropriate module.
  3. Declare it in the @NgModule declarations array.
54. What happens if browserModule used in feature module?

If you do import BrowserModule into a lazy loaded feature module, Angular returns an error telling you to use CommonModule instead. Because BrowserModule’s providers are for the entire app so it should only be in the root module, not in feature module. Whereas Feature modules only need the common directives in CommonModule.

55. What are the types of feature modules?

Below are the five categories of feature modules,

  1. Domain: Deliver a user experience dedicated to a particular application domain(For example, place an order, registration etc)
  2. Routed: These are domain feature modules whose top components are the targets of router navigation routes.
  3. Routing: It provides routing configuration for another module.
  4. Service: It provides utility services such as data access and messaging(For example, HttpClientModule)
  5. Widget: It makes components, directives, and pipes available to external modules(For example, third-party libraries such as Material UI)
56. What is the recommendation for provider scope?

You should always provide your service in the root injector unless there is a case where you want the service to be available only if you import a particular @NgModule.

57. How do you restrict provider scope to a module?

It is possible to restrict service provider scope to a specific module instead making available to entire application. There are two possible ways to do it.

  1. Using providedIn in service:
    import { Injectable } from '@angular/core';
    import { SomeModule } from './some.module';
    @Injectable({
    providedIn: SomeModule,
    })
    export class SomeService {
    }
  2. Declare provider for the service in module:
    import { NgModule } from '@angular/core';
    import { SomeService } from './some.service';
    @NgModule({
    providers: [SomeService],
    })
    export class SomeModule {
    }
58. How do you provide a singleton service?

There are two possible ways to provide a singleton service.

  1. Set the providedIn property of the @Injectable() to "root". This is the preferred way(starting from Angular 6.0) of creating a singleton service since it makes your services tree-shakable.
    import { Injectable } from '@angular/core';
    @Injectable({
    providedIn: 'root',
    })
    export class MyService {
    }
  2. Include the service in root module or in a module that is only imported by root module. It has been used to register services before Angular 6.0.
    @NgModule({
    ...
    providers: [MyService],
    ...
    })
59. What are the different ways to remove duplicate service registration?

If a module defines provides and declarations then loading the module in multiple feature modules will duplicate the registration of the service. Below are the different ways to prevent this duplicate behavior.

  1. Use the providedIn syntax instead of registering the service in the module.
  2. Separate your services into their own module.
  3. Define forRoot() and forChild() methods in the module.
60. How does forRoot method helpful to avoid duplicate router instances?

If the RouterModule module didn’t have forRoot() static method then each feature module would instantiate a new Router instance, which leads to broken application due to duplicate instances. After using forRoot() method, the root application module imports RouterModule.forRoot(...) and gets a Router, and all feature modules import RouterModule.forChild(...) which does not instantiate another Router.

61. What is a shared module?

The Shared Module is the module in which you put commonly used directives, pipes, and components into one module that is shared(import it) throughout the application. For example, the below shared module imports CommonModule, FormsModule for common directives and components, pipes and directives based on the need,

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { UserComponent } from './user.component';
import { NewUserDirective } from './new-user.directive';
import { OrdersPipe } from './orders.pipe';
@NgModule({
imports:      [ CommonModule ],
declarations: [ UserComponent, NewUserDirective, OrdersPipe ],
exports:      [ UserComponent, NewUserDirective, OrdersPipe,
CommonModule, FormsModule ]
})
export class SharedModule { }
62. Can I share services using modules?

No, it is not recommended to share services by importing module. i.e Import modules when you want to use directives, pipes, and components only. The best approach to get a hold of shared services is through 'Angular dependency injection' because importing a module will result in a new service instance.

63. How do you get current direction for locales??

In Angular 9.1, the API method getLocaleDirection can be used to get the current direction in your app. This method is useful to support Right to Left locales for your Internationalization based applications.

import { getLocaleDirection, registerLocaleData } from '@angular/common';
import { LOCALE_ID } from '@angular/core';
import localeAr from '@angular/common/locales/ar';
...
constructor(@Inject(LOCALE_ID) locale) {
const directionForLocale = getLocaleDirection(locale); // Returns 'rtl' or 'ltr' based on the current locale
registerLocaleData(localeAr, 'ar-ae');
const direction = getLocaleDirection('ar-ae'); // Returns 'rtl'
// Current direction is used to provide conditional logic here
}
64. What is ngcc?

The ngcc(Angular Compatibility Compiler) is a tool which upgrades node_module compiled with non-ivy ngc into ivy compliant format. The postinstall script from package.json will make sure your node_modules will be compatible with the Ivy renderer.

"scripts": {
"postinstall": "ngcc"
}

Whereas, Ivy compiler (ngtsc), which compiles Ivy-compatible code.

65. What classes should not be added to declarations?

The below class types shouldn't be added to declarations

  1. A class which is already declared in any another module.
  2. Directives imported from another module.
  3. Module classes.
  4. Service classes.
  5. Non-Angular classes and objects, such as strings, numbers, functions, entity models, configurations, business logic, and helper classes.
66. What is NoopZone?

Zone is loaded/required by default in Angular applications and it helps Angular to know when to trigger the change detection. This way, it make sures developers focus on application development rather core part of Angular. You can also use Angular without Zone but the change detection need to be implemented on your own and noop zone need to be configured in bootstrap process. Let's follow the below two steps to remove zone.js,

  1. Remove the zone.js import from polyfills.ts. ```js /***
  • Zone JS is required by default for Angular itself.
  • / // import 'zone.js/dist/zone'; // Included with Angular CLI. ```
  1. Bootstrap Angular with noop zone in src/main.ts.
    platformBrowserDynamic().bootstrapModule(AppModule, {ngZone: 'noop'})
    .catch(err => console.error(err));
67. What is a zone context?

Execution Context is an abstract concept that holds information about the environment within the current code being executed. A zone provides an execution context that persists across asynchronous operations is called as zone context. For example, the zone context will be same in both outside and inside setTimeout callback function,

zone.run(() => {
// outside zone
expect(zoneThis).toBe(zone);
setTimeout(function() {
// the same outside zone exist here
expect(zoneThis).toBe(zone);
});
});

The current zone is retrieved through Zone.current.

68. What are the lifecycle hooks of a zone?

There are four lifecycle hooks for asynchronous operations from zone.js.

  1. onScheduleTask: This hook triggers when a new asynchronous task is scheduled. For example, when you call setTimeout()
    onScheduleTask: function(delegate, curr, target, task) {
    console.log('new task is scheduled:', task.type, task.source);
    return delegate.scheduleTask(target, task);
    }
  2. onInvokeTask: This hook triggers when an asynchronous task is about to execute. For example, when the callback of setTimeout() is about to execute.
    onInvokeTask: function(delegate, curr, target, task, applyThis, applyArgs) {
    console.log('task will be invoked:', task.type, task.source);
    return delegate.invokeTask(target, task, applyThis, applyArgs);
    }
  3. onHasTask: This hook triggers when the status of one kind of task inside a zone changes from stable(no tasks in the zone) to unstable(a new task is scheduled in the zone) or from unstable to stable.
    onHasTask: function(delegate, curr, target, hasTaskState) {
    console.log('task state changed in the zone:', hasTaskState);
    return delegate.hasTask(target, hasTaskState);
    }
  4. onInvoke: This hook triggers when a synchronous function is going to execute in the zone.
    onInvoke: function(delegate, curr, target, callback, applyThis, applyArgs) {
    console.log('the callback will be invoked:', callback);
    return delegate.invoke(target, callback, applyThis, applyArgs);
    }
69. What are the methods of NgZone used to control change detection?

NgZone service provides a run() method that allows you to execute a function inside the angular zone. This function is used to execute third party APIs which are not handled by Zone and trigger change detection automatically at the correct time.

export class AppComponent implements OnInit {
constructor(private ngZone: NgZone) {}
ngOnInit() {
// use ngZone.run() to make the asynchronous operation in the angular zone
this.ngZone.run(() => {
someNewAsyncAPI(() => {
// update the data of the component
});
});
}
}

Whereas runOutsideAngular() method is used when you don't want to trigger change detection.

export class AppComponent implements OnInit {
constructor(private ngZone: NgZone) {}
ngOnInit() {
// Use this method when you know no data will be updated
this.ngZone.runOutsideAngular(() => {
setTimeout(() => {
// update component data and don't trigger change detection
});
});
}
}
70. What is an optional dependency?

The optional dependency is a parameter decorator to be used on constructor parameters, which marks the parameter as being an optional dependency. Due to this, the DI framework provides null if the dependency is not found. For example, If you don't register a logger provider anywhere, the injector sets the value of logger(or logger service) to null in the below class.

import { Optional } from '@angular/core';
constructor(@Optional() private logger?: Logger) {
if (this.logger) {
this.logger.log('This is an optional dependency message');
} else {
console.log('The logger is not registered');
}
}
71. What are the state CSS classes provided by ngModel?

The ngModel directive updates the form control with special Angular CSS classes to reflect it's state. Let's find the list of classes in a tabular format, | Form control state | If true | If false | |---- | --------- | --- | | Visited | ng-touched | ng-untouched | | Value has changed | ng-dirty | ng-pristine | | Value is valid| ng-valid | ng-invalid |

72. What are the types of validator functions?

In reactive forms, the validators can be either synchronous or asynchronous functions,

  1. Sync validators: These are the synchronous functions which take a control instance and immediately return either a set of validation errors or null. Also, these functions passed as second argument while instantiating the form control. The main use cases are simple checks like whether a field is empty, whether it exceeds a maximum length etc.
  2. Async validators: These are the asynchronous functions which take a control instance and return a Promise or Observable that later emits a set of validation errors or null. Also, these functions passed as second argument while instantiating the form control. The main use cases are complex validations like hitting a server to check the availability of a username or email. The representation of these validators looks like below
    this.myForm = formBuilder.group({
    firstName: ['value'],
    lastName: ['value', *Some Sync validation function*],
    email: ['value', *Some validation function*, *Some asynchronous validation function*]
    });
73. How do you optimize the performance of async validators?

Since all validators run after every form value change, it creates a major impact on performance with async validators by hitting the external API on each keystroke. This situation can be avoided by delaying the form validity by changing the updateOn property from change (default) to submit or blur. The usage would be different based on form types,

  1. Template-driven forms: Set the property on ngModelOptions directive
    <input [(ngModel)]="name" [ngModelOptions]="{updateOn: 'blur'}">
  2. Reactive-forms: Set the property on FormControl instance
    name = new FormControl('', {updateOn: 'blur'});

© 2020 Tiqa