Angular Questions
Angular Questions
Angular Questions
AngularJS Angular
It is based on MVC architecture This is based on Service/Controller
Introduced the typescript to write the
This uses use JavaScript to build the application
application
Based on controllers concept This is a component based UI approach
Not a mobile friendly framework Developed considering mobile platform
Difficulty in SEO friendly application
Ease to create SEO friendly applications
development
What is TypeScript?
TypeScript is a typed superset of JavaScript created by Microsoft that adds optional types,
classes, async/await, and many other features, and compiles to plain JavaScript. Angular built
entirely in TypeScript and used as a primary language. You can install it globally as
document.body.innerHTML = greeter(user);
The greeter method allows only string type as argument.
1. Component: These are the basic building blocks of angular application to control HTML
views.
2. Modules: An angular module is set of angular basic building blocks like component,
directives, services etc. An application is divided into logical pieces and each piece of
code is called as "module" which perform a single task.
3. Templates: This represent the views of an Angular application.
4. Services: It is used to create components which can be shared across the entire
application.
5. Metadata: This can be used to add more data to an Angular class.
What are directives?
Directives add behaviour to an existing DOM element or an existing component instance.
Now this directive extends HTML element behavior with a yellow background as below
Components are the most basic UI building block of an Angular app which formed a tree of
Angular components. These components are subset of directives. Unlike directives, components
always have a template and only one component can be instantiated per an element in a template.
Let's see a simple example of Angular component
@Component ({
selector: 'my-app',
template: ` <div>
<h1>{{title}}</h1>
<div>Learn Angular6 with examples</div>
</div> `,
})
Component Directive
Component Directive
To register a component we use @Component meta- To register directives we use @Directive
data annotation meta-data annotation
Directive is used to add behavior to an
Components are typically used to create UI widgets
existing DOM element
Component is used to break up the application into Directive is use to design re-usable
smaller components components
Only one component can be present per DOM Many directives can be used per DOM
element element
@View decorator or templateurl/template are
Directive doesn't use View
mandatory
What is a template?
A template is a HTML view where you can display data by binding controls to properties of an
Angular component. You can store your component's template in one of two places. You can
define it inline using the template property, or you can define the template in a separate HTML
file and link to it in the component metadata using the @Component decorator's templateUrl
property. Using inline template with template syntax,
@Component ({
selector: 'my-app',
template: '
<div>
<h1>{{title}}</h1>
<div>Learn Angular</div>
</div>
'
})
@Component ({
selector: 'my-app',
templateUrl: 'app/app.component.html'
})
What is a module?
Modules are logical boundaries in your application and the application is divided into separate
modules to separate the functionality of your application. Lets take an example of app.module.ts
root module declared with @NgModule decorator as below,
@NgModule ({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
1. The imports option is used to import other dependent modules. The BrowserModule is
required by default for any web based angular application
2. The declarations option is used to define components in the respective module
3. The bootstrap option tells Angular which Component to bootstrap in the application
as follows,
The description of each lifecycle method is as below,
1. ngOnChanges: When the value of a data bound property changes, then this method is
called.
2. ngOnInit: This is called whenever the initialization of the directive/component after
Angular first displays the data-bound properties happens.
3. ngDoCheck: This is for the detection and to act on changes that Angular can't or won't
detect on its own.
4. ngAfterContentInit: This is called in response after Angular projects external content
into the component's view.
5. ngAfterContentChecked: This is called in response after Angular checks the content
projected into the component.
6. ngAfterViewInit: This is called in response after Angular initializes the component's
views and child views.
7. ngAfterViewChecked: This is called in response after Angular checks the component's
views and child views.
8. ngOnDestroy: This is the cleanup phase just before Angular destroys the
directive/component.
1. From the Component to the DOM: Interpolation: {{ value }}: Adds the value of a
property from the component
Property binding: [property]=”value”: The value is passed from the component to the specified
property or simple HTML attribute
<button (click)="logout()"></button>
3. Two-way binding: Two-way data binding: [(ngModel)]=”value”: Two-way data
binding allows to have the data flow both ways. For example, in the below code snippet,
both the email DOM input and component email property are in sync
What is metadata?
Metadata is used to decorate a class so that it can configure the expected behavior of the class.
The metadata is represented by decorators
@Component({
selector: 'my-component',
template: '<div>Class decorator</div>',
})
export class MyComponent {
constructor() {
console.log('Hey I am a component!');
}
}
@NgModule({
imports: [],
declarations: [],
})
export class MyModule {
constructor() {
console.log('Hey I am a module!');
}
}
2. Property decorators Used for properties inside classes, e.g. @Input and @Output
@Component({
selector: 'my-component',
template: '<div>Property decorator</div>'
})
@Component({
selector: 'my-component',
template: '<div>Method decorator</div>'
})
export class MyComponent {
@HostListener('click', ['$event'])
onHostClick(event: Event) {
// clicked, `event` available
}
}
4. Parameter decorators Used for parameters inside class constructors, e.g. @Inject
@Component({
selector: 'my-component',
template: '<div>Parameter decorator</div>'
})
export class MyComponent {
constructor(@Inject(MyService) myService) {
console.log(myService); // MyService
}
}
Below are the list of few commands, which will come handy while creating angular projects
ngOnInit(){
//called after the constructor and called after the first ngOnChanges()
}
}
What is a service?
A service is used when a common functionality needs to be provided to various modules.
Services allow for greater separation of concerns for your application and better modularity by
allowing you to extract common functionality out of components. Let's create a repoService
which can be used across components,
fetchAll(){
return this.http.get('https://api.github.com/repositories');
}
}
The above service uses Http service as a dependency.
@Component({
selector: 'async-observable-pipe',
template: `<div><code>observable|async</code>:
Time: {{ time | async }}</div>`
})
export class AsyncObservablePipeComponent {
time = new Observable(observer =>
setInterval(() => observer.next(new Date().toString()), 2000)
);
}
The user variable in the ngFor double-quoted instruction is a template input variable
<p *ngIf="user.age > 18">You are not eligible for student pass!</p>
Note: Angular isn't showing and hiding the message. It is adding and removing the paragraph
element from the DOM. That improves performance, especially in the larger projects with many
data bindings.
What is interpolation?
Interpolation is a special syntax that Angular converts into property binding. It’s a convenient
alternative to property binding. It is represented by double curly braces({{}}). The text between
the braces is often the name of a component property. Angular replaces that name with the string
value of the corresponding component property. Let's take an example,
<h3>
{{title}}
<img src="{{url}}" style="height:30px">
</h3>
In the example above, Angular evaluates the title and url properties and fills in the blanks, first
displaying a bold application title and then a URL.
In the above expression, editProfile is a template statement. The below JavaScript syntax
expressions are not allowed.
1. new
2. increment and decrement operators, ++ and --
3. operator assignment, such as += and -=
4. the bitwise operators | and &
5. the template expression operators
@Component({
selector: 'app-birthday',
template: `<p>Birthday is {{ birthday | date }}</p>`
})
export class BirthdayComponent {
birthday = new Date(1987, 6, 18); // June 18, 1987
}
@Component({
selector: 'app-birthday',
template: `<p>Birthday is {{ birthday | date:'dd/mm/yyyy'}}</p>` //
18/06/1987
})
export class BirthdayComponent {
birthday = new Date(1987, 6, 18);
}
Note: The parameter value can be any valid template expression, such as a string literal or a
component property.
@Component({
selector: 'app-birthday',
template: `<p>Birthday is {{ birthday | date:'fullDate' |
uppercase}} </p>` // THURSDAY, JUNE 18, 1987
})
export class BirthdayComponent {
birthday = new Date(1987, 6, 18);
}
1. A pipe is a class decorated with pipe metadata @Pipe decorator, which you import from
the core Angular library For example,
@Pipe({name: 'myCustomPipe'})
2. The pipe class implements the PipeTransform interface's transform method that accepts
an input value followed by optional parameters and returns the transformed value. The
structure of pipeTransform would be as below,
interface PipeTransform {
transform(value: any, ...args: any[]): any
}
3. The @Pipe decorator allows you to define the pipe name that you'll use within template
expressions. It must be a valid JavaScript identifier.
@Pipe({name: 'customFileSizePipe'})
export class FileSizePipe implements PipeTransform {
transform(size: number, extension: string = 'MB'): string {
return (size / (1024 * 1024)).toFixed(2) + extension;
}
}
Now you can use the above pipe in template expression as below,
template: `
<h2>Find the size of a file</h2>
<p>Size: {{288966 | customFileSizePipe: 'GB'}}</p>
`
/* JavaScript imports */
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
@Injectable()
export class UserProfileService {
constructor(private http: HttpClient) { }
getUserProfile() {
return this.http.get(this.userProfileUrl);
}
}
fetchUserProfile() {
this.userProfileService.getUserProfile()
.subscribe((data: User) => this.user = {
id: data['userId'],
name: data['firstName'],
city: data['city']
});
}
Since the above service method returns an Observable which needs to be subscribed in the
component.
getUserResponse(): Observable<HttpResponse<User>> {
return this.http.get<User>(
this.userUrl, { observe: 'response' });
}
Now HttpClient.get() method returns an Observable of typed HttpResponse rather than just the
JSON data.
fetchUser() {
this.userService.getProfile()
.subscribe(
(data: User) => this.userProfile = { ...data }, // success path
error => this.error = error // error path
);
}
It is always a good idea to give the user some meaningful feedback instead of displaying the raw
error object returned from HttpClient.
What is RxJS?
RxJS is a library for composing asynchronous and callback-based code in a functional, reactive
style using Observables. Many APIs such as HttpClient produce and consume RxJS Observables
and also uses operators for processing observables. For example, you can import observables and
operators for using HttpClient as below,
What is subscribing?
An Observable instance begins publishing values only when someone subscribes to it. So you
need to subscribe by calling the subscribe() method of the instance, passing an observer object
to receive the notifications. Let's take an example of creating and subscribing to a simple
observable, with an observer that logs the received message to the console.
// Execute with the observer object and Prints out each item
myObservable.subscribe(myObserver);
// => Observer got a next value: 1
// => Observer got a next value: 2
// => Observer got a next value: 3
// => Observer got a next value: 4
// => Observer got a next value: 5
// => Observer got a complete notification
What is an observable?
An Observable is a unique Object similar to a Promise that can help manage async code.
Observables are not part of the JavaScript language so we need to rely on a popular Observable
library called RxJS. The observables are created using new keyword. Let see the simple example
of observable,
What is an observer?
Observer is an interface for a consumer of push-based notifications delivered by an Observable.
It has below structure,
interface Observer<T> {
closed?: boolean;
next: (value: T) => void;
error: (err: any) => void;
complete: () => void;
}
A handler that implements the Observer interface for receiving observable notifications will be
passed as a parameter for observable as below,
myObservable.subscribe(myObserver);
Note: If you don't supply a handler for a notification type, the observer ignores notifications of
that type.
What is the difference between promise and observable?
Below are the list of differences between promise and observable,
Observable Promise
Declarative: Computation does not start until subscription so that they Execute immediately on
can be run whenever you need the result creation
Provide multiple values over time Provide only one
Subscribe method is used for error handling which makes centralized Push errors to the child
and predictable error handling promises
Provides chaining and subscription to handle complex applications Uses only .then() clause
45.
What is multicasting?
Multi-casting is the practice of broadcasting to a list of multiple subscribers in a single execution.
Let's demonstrate the multi-casting feature,
myObservable.subscribe({
next(num) { console.log('Next num: ' + num)},
error(err) { console.log('Received an errror: ' + err)}
});
myObservable.subscribe(
x => console.log('Observer got a next value: ' + x),
err => console.error('Observer got an error: ' + err),
() => console.log('Observer got a complete notification')
);
The RxJS library also provides below utility functions for creating and working with
observables.
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. The flow chart of the custom
elements functionality would be as follows,
@Component(...)
class MyContainer {
@Input() message: string;
}
After applying types typescript validates input value and their types,
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'red';
}
}
ng serve
<router-outlet></router-outlet>
<!-- Routed components go here -->
<h1>Angular Router</h1>
<nav>
<a routerLink="/todosList" >List of todos</a>
<a routerLink="/completed" >Completed todos</a>
</nav>
<router-outlet></router-outlet>
@Component({templateUrl:'template.html'})
class MyComponent {
constructor(router: Router) {
const state: RouterState = router.routerState;
const root: ActivatedRoute = state.root;
const child = root.firstChild;
const id: Observable<string> = child.params.map(p => p.id);
//...
}
}
1. NavigationStart,
2. RouteConfigLoadStart,
3. RouteConfigLoadEnd,
4. RoutesRecognized,
5. GuardsCheckStart,
6. ChildActivationStart,
7. ActivationStart,
8. GuardsCheckEnd,
9. ResolveStart,
10. ResolveEnd,
11. ActivationEnd
12. ChildActivationEnd
13. NavigationEnd,
14. NavigationCancel,
15. NavigationError
16. Scroll
@Component({...})
class MyComponent {
constructor(route: ActivatedRoute) {
const id: Observable<string> = route.params.pipe(map(p => p.id));
const url: Observable<string> = route.url.pipe(map(segments =>
segments.join('')));
// route.data includes both `data` and `resolve`
const user = route.data.pipe(map(d => d.user));
}
}
@NgModule({
imports: [
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } // <-- debugging purposes only
)
// other imports here
],
...
})
export class AppModule { }
1. Just-in-Time (JIT)
2. Ahead-of-Time (AOT)
What is JIT?
Just-in-Time (JIT) is a type of compilation that compiles your app in the browser at runtime. JIT
compilation is the default when you run the ng build (build only) or ng serve (build and serve
locally) CLI commands. i.e, the below commands used for JIT compilation,
ng build
ng serve
What is AOT?
Ahead-of-Time (AOT) is a type of compilation that compiles your app at build time. For AOT
compilation, include the --aot option with the ng build or ng serve command as below,
ng build --aot
ng serve --aot
Note: The ng build command with the --prod meta-flag (ng build --prod) compiles with AOT
by default.
@Component({
providers: [{
provide: MyService, useFactory: () => getService()
}]
})
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.
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
@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.
@NgModule({
declarations: wrapInArray(TypicalComponent)
})
export class TypicalModule {}
@NgModule({
declarations: [TypicalComponent]
})
export class TypicalModule {}
15. Function calls are not supported: The compiler does not currently support function
expressions or lambda functions. For example, you cannot set a provider's useFactory to
an anonymous function or arrow function as below.
16. providers: [
17. { provide: MyStrategy, useFactory: function() { ... } },
18. { provide: OtherStrategy, useFactory: () => { ... } }
]
19. Destructured variable or constant not supported: The compiler does not support
references to variables assigned by destructuring. For example, you cannot write
something like this:
20. import { user } from './user';
21.
22. // destructured assignment to name and age
23. const {name, age} = user;
24. ... //metadata
25. providers: [
26. {provide: Name, useValue: name},
27. {provide: Age, useValue: age},
]
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
{
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
@Component({
selector: 'my-component',
template: '{{user.contacts.email}}'
})
class MyComponent {
user?: User;
}
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}}'
@Component({
selector: 'my-component',
template: '<span *ngIf="user"> {{user.name}} contacted through
{{contact!.email}} </span>'
})
class MyComponent {
user?: User;
contact?: Contact;
@Component({
selector: 'my-component',
template: '<span *ngIf="user"> {{user.contact.email}} </span>'
})
class MyComponent {
user?: User;
}
1. Angular packages: Angular core and optional modules; their package names begin
@angular/.
2. Support packages: Third-party libraries that must be present for Angular apps to run.
3. Polyfill packages: Polyfills plug gaps in a browser's JavaScript implementation.
What is zone?
A Zone is an execution context that persists across async tasks. Angular relies on zone.js to run
Angular's change detection processes when native JavaScript operations raise events
What is codelyzer?
Codelyzer provides set of tslint rules for static code analysis of Angular TypeScript projects. ou
can run the static code analyzer over web apps, NativeScript, Ionic etc. Angular CLI has support
for this and it can be use as below,
ng new codelyzer
ng lint
What are the steps to use animation module?
You need to follow below steps to implement animation in your angular project,
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule
],
declarations: [ ],
bootstrap: [ ]
})
export class AppModule { }
import {
trigger,
state,
style,
animate,
transition,
// ...
} from '@angular/animations';
3. Adding the animation metadata property: add a metadata property called animations:
within the @Component() decorator in component files(for example,
src/app/app.component.ts)
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
animations: [
// animation triggers go here
]
})
What is State function?
Angular's state() function is used to define different states to call at the end of each transition.
This function takes two arguments: a unique name like open or closed and a style() function. For
example, you can write a open state function
state('open', style({
height: '300px',
opacity: 0.5,
backgroundColor: 'blue'
})),
state('close', style({
height: '100px',
opacity: 0.8,
backgroundColor: 'green'
})),
@Component({
selector: 'app-animate',
templateUrl: `<div [@changeState]="currentState" class="myblock mx-
auto"></div>`,
styleUrls: `.myblock {
background-color: green;
width: 300px;
height: 250px;
border-radius: 5px;
margin: 5rem;
}`,
animations: [
trigger('changeState', [
state('state1', style({
backgroundColor: 'green',
transform: 'scale(1)'
})),
state('state2', style({
backgroundColor: 'red',
transform: 'scale(1.5)'
})),
transition('*=>state1', animate('300ms')),
transition('*=>state2', animate('2000ms'))
])
]
})
export class AnimateComponent implements OnInit {
@Input() currentState;
constructor() { }
ngOnInit() {
}
}
1. You can enable ivy in a new project by using the --enable-ivy flag with the ng new
command
{
"compilerOptions": { ... },
"angularCompilerOptions": {
"enableIvy": true
}
}
{
"projects": {
"my-project": {
"architect": {
"build": {
"options": {
...
"aot": true,
}
}
}
}
}
}
After that add the following to the "compilerOptions" section of your project's tsconfig.json
"plugins": [
{"name": "@angular/language-service"}
]
Note: The completion and diagnostic services works for .ts files only. You need to use custom
plugins for supporting HTML files.
Explain the features provided by Angular Language Service?
Basically there are 3 main features provided by Angular Language Service,
3. Navigation: Navigation allows you to hover a component, directive, module and then
click and press F12 to go directly to its definition.
Note: You may need to refactor your initial scaffolding web worker code for sending messages
to and from.
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.
1. @Component()
2. @Directive()
3. @Pipe()
4. @Injectable()
5. @NgModule()
@Input() myProperty;
@Output() myEvent = new EventEmitter();
What is a DI token?
A DI token is a lookup token associated with a dependency provider in dependency injection
system. The injector maintains an internal token-provider map that it references when asked for a
dependency and the DI token is the key to the map. Let's take example of DI Token usage,
A Subject is like an Observable, but can multicast to many Observers. Subjects are like
EventEmitters: they maintain a registry of many listeners.
subject.subscribe({
next: (v) => console.log(`observerA: ${v}`)
});
subject.subscribe({
next: (v) => console.log(`observerB: ${v}`)
});
subject.next(1);
subject.next(2);
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.
ng add @angular/bazel
2. Use in a new application: Install the package and create the application with collection
option
When you use ng build and ng serve commands, Bazel is used behind the scenes and outputs the
results in dist/bin folder.
How do you run Bazel directly?
Sometimes you may want to bypass the Angular CLI builder and run Bazel directly using Bazel
CLI. You can install it globally using @bazel/bazel npm package. i.e, Bazel CLI is available
under @bazel/bazel package. After you can apply the below common commands,
bazel build [targets] // Compile the default output artifacts of the given
targets.
bazel test [targets] // Run the tests with *_test targets found in the
pattern.
bazel run [target]: Compile the program represented by target and then run
it.
<input #uname>
and define view child directive and access it in ngAfterViewInit lifecycle hook
@ViewChild('uname') input;
ngAfterViewInit() {
console.log(this.input.nativeElement.value);
}
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
(or)
let headers = new HttpHeaders().set('header1', headerValue1); // create
header object
headers = headers.append('header2', headerValue2); // add a new header,
creating a new object
headers = headers.append('header3', headerValue3); // add another header
1. The first build contains ES2015 syntax which takes the advantage of built-in support in
modern browsers, ships less polyfills, and results in a smaller bundle size.
2. The second build contains old ES5 syntax to support older browsers with all necessary
polyfills. But this results in a larger bundle size.
Note: This strategy is used to support multiple browsers but it only load the code that the
browser needs.
buildTarget.options.optimization = true;
addBuildTargetOption();
It supports the most recent two versions of all major browsers. The latest version of Angular
material is 8.1.1
@NgModule({
imports: [
// Other NgModule imports...
LocationUpgradeModule.config()
]
})
export class AppModule {}
What is NgUpgrade?
NgUpgrade is a library put together by the Angular team, which you can use in your applications
to mix and match AngularJS and Angular components and bridge the AngularJS and Angular
dependency injection systems.
Note: A chrome browser also opens and displays the test output in the "Jasmine HTML
Reporter".
1. Mandatory polyfills: These are installed automatically when you create your project
with ng new command and the respective import statements enabled in 'src/polyfills.ts'
file.
2. Optional polyfills: You need to install its npm package and then create import statement
in 'src/polyfills.ts' file. For example, first you need to install below npm package for
adding web animations (optional) polyfill.
import 'web-animations-js';
1. ApplicationRef.tick(): Invoke this method to explicitly process change detection and its
side-effects. It check the full component tree.
2. NgZone.run(callback): It evaluate the callback function inside the Angular zone.
3. ChangeDetectorRef.detectChanges(): It detects only the components and it's children.
1. Angular 1 • Angular 1 (AngularJS) is the first angular framework released in the year
2010. • AngularJS is not built
?
?
?
?
?
?
?