Angular Interview Questions for Freshers
Question: How do you handle HTTP requests in Angular?
Answer:
In Angular, HTTP requests are handled using the HttpClient
module, which is part of Angular’s @angular/common/http
package. The HttpClient
provides a simplified API for making HTTP requests such as GET
, POST
, PUT
, DELETE
, etc., and returns Observables that you can subscribe to for handling the asynchronous data.
Handling HTTP requests in Angular involves the following steps:
- Importing the
HttpClientModule
. - Using the
HttpClient
service to send HTTP requests. - Subscribing to Observables to handle the asynchronous responses or errors.
Step 1: Import the HttpClientModule
:
First, you need to import the HttpClientModule
in your application’s root module (app.module.ts
) so that Angular can inject the HttpClient
service into your components and services.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http'; // Import HttpClientModule
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule], // Add HttpClientModule here
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 2: Inject the HttpClient
Service:
Next, inject the HttpClient
service into your component or service to make HTTP requests. The HttpClient
has methods like get()
, post()
, put()
, delete()
, and patch()
to make different types of requests.
Example of a GET Request:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts'; // Example API
constructor(private http: HttpClient) { }
// GET Request using HttpClient
getPosts(): Observable<any> {
return this.http.get<any>(this.apiUrl); // Makes a GET request
}
}
In this example:
getPosts()
is a method that makes an HTTPGET
request to retrieve data from an API.- The return type of
http.get()
is anObservable
, which will emit the response data when the request completes.
Example of a POST Request:
To send data to the server (for example, creating a new post), use the post()
method of HttpClient
.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts'; // Example API
constructor(private http: HttpClient) { }
// POST Request using HttpClient
createPost(postData: any): Observable<any> {
return this.http.post<any>(this.apiUrl, postData); // Sends data to API
}
}
In this example:
createPost()
sends a POST request with thepostData
object to the server.- The response will be emitted through the Observable.
Step 3: Subscribing to the Observable:
After you make an HTTP request, you subscribe to the returned Observable in order to get the actual data or handle errors.
Example: Subscribing in a Component:
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-root',
template: `
<h1>Angular HTTP Example</h1>
<div *ngFor="let post of posts">
<p>{{ post.title }}</p>
</div>
`
})
export class AppComponent implements OnInit {
posts: any[] = [];
constructor(private dataService: DataService) { }
ngOnInit() {
// Subscribe to the Observable returned by getPosts() method
this.dataService.getPosts().subscribe(
(response) => {
this.posts = response; // Handle the response and assign it to the posts array
},
(error) => {
console.error('Error occurred:', error); // Handle error
}
);
}
}
In this component:
- The
ngOnInit()
lifecycle hook subscribes to the Observable returned by thegetPosts()
method fromDataService
. - The data (
response
) is assigned to theposts
array, which is then displayed in the template.
Handling Errors:
You can handle errors in HTTP requests using the catchError
operator from RxJS. It’s important to handle errors to prevent your application from crashing if something goes wrong with the HTTP request.
Example: Handling Errors:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) { }
// Handling errors with catchError
getPosts(): Observable<any> {
return this.http.get<any>(this.apiUrl).pipe(
catchError(error => {
console.error('Error occurred:', error);
return of([]); // Return a fallback value (empty array) in case of error
})
);
}
}
In this example:
- The
catchError
operator intercepts any errors that occur during the HTTP request. - It logs the error and returns a fallback value (
of([])
), which prevents the Observable from failing and allows the application to continue running.
Configuring HTTP Headers and Parameters:
Sometimes you need to include headers, query parameters, or authentication tokens with your HTTP requests.
Example: Custom Headers:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) { }
// GET Request with custom headers
getPostsWithHeaders(): Observable<any> {
const headers = new HttpHeaders({
'Authorization': 'Bearer your-token',
'Custom-Header': 'Header-Value'
});
return this.http.get<any>(this.apiUrl, { headers });
}
}
In this example:
HttpHeaders
is used to set custom headers for the HTTP request, such as an Authorization token.- The
headers
are passed as an option to thehttp.get()
method.
Example: Query Parameters:
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) { }
// GET Request with query parameters
getPostsWithParams(page: number, limit: number): Observable<any> {
const params = new HttpParams().set('page', page.toString()).set('limit', limit.toString());
return this.http.get<any>(this.apiUrl, { params });
}
}
In this example:
HttpParams
is used to build query parameters for the HTTP request.- The
params
are passed as an option to thehttp.get()
method to send them along with the request.
Conclusion:
To handle HTTP requests in Angular:
- Import the
HttpClientModule
into your application. - Inject
HttpClient
into your service or component to make requests. - Use
get()
,post()
,put()
,delete()
, etc., methods to interact with APIs. - Subscribe to the returned Observable to handle responses and errors.
- Use RxJS operators like
catchError
,map
, and others to manage data and errors effectively.
This approach provides a reactive, declarative way of handling HTTP requests, making Angular applications both scalable and maintainable.
Question: What are Angular pipes? Can you explain how they are used?
Answer:
In Angular, pipes are a powerful feature used to transform data in templates. They allow you to apply transformations to data before it is displayed to the user, such as formatting dates, filtering lists, or transforming text. Pipes take the input data and return a transformed value to be rendered in the view.
Key Points about Angular Pipes:
- Pipes are simple functions: A pipe is essentially a function that takes an input value, applies a transformation, and returns the transformed value.
- Built-in pipes: Angular provides a set of built-in pipes, such as
DatePipe
,CurrencyPipe
,UpperCasePipe
,LowerCasePipe
, and more. - Custom pipes: You can also create custom pipes to implement specific transformations for your application.
- Pure and Impure pipes: By default, Angular pipes are pure, meaning they only update when the input value changes. However, pipes can be made impure if they depend on something other than input values (e.g., external data or state).
Using Built-in Pipes:
1. Common Built-in Pipes:
date
: Formats a date according to the specified format.currency
: Formats a number as currency.uppercase
andlowercase
: Transforms text to uppercase or lowercase.json
: Converts an object into a JSON-formatted string.slice
: Slices a string or array.async
: Resolves an asynchronous value (like anObservable
orPromise
).
Examples of Using Built-in Pipes:
<!-- Format a date -->
<p>{{ today | date:'short' }}</p>
<!-- Format a number as currency -->
<p>{{ amount | currency:'USD' }}</p>
<!-- Convert text to uppercase -->
<p>{{ text | uppercase }}</p>
<!-- Convert text to lowercase -->
<p>{{ text | lowercase }}</p>
<!-- Slice an array or string -->
<p>{{ ['apple', 'banana', 'cherry'] | slice:1:3 }}</p>
<!-- JSON representation of an object -->
<p>{{ person | json }}</p>
Explanation of the Above Examples:
date
:today | date:'short'
transforms aDate
object into a human-readable date format (e.g., “1/24/2024, 10:25 AM”).currency
:amount | currency:'USD'
converts the numericamount
into a currency format, with$
symbol for USD.uppercase
:text | uppercase
converts thetext
to uppercase letters.lowercase
:text | lowercase
converts thetext
to lowercase letters.slice
:['apple', 'banana', 'cherry'] | slice:1:3
returns a subarray from index 1 to index 3, resulting in['banana', 'cherry']
.json
:person | json
converts an object into a JSON string representation.
Creating Custom Pipes:
While Angular provides many built-in pipes, you can create your own custom pipes for more specific transformations.
Steps to Create a Custom Pipe:
- Create a Pipe class using the
@Pipe
decorator. - Implement the
transform()
method, which will contain the logic for transforming the input data. - Register the custom pipe in an Angular module.
Example: Creating a Custom Pipe
Let’s create a custom pipe that capitalizes the first letter of each word in a string.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'capitalize' // Custom name of the pipe
})
export class CapitalizePipe implements PipeTransform {
transform(value: string): string {
if (!value) return value; // Return if value is empty or null
return value.replace(/\b\w/g, (char) => char.toUpperCase());
}
}
Using the Custom Pipe in the Template:
After creating the custom pipe, you can use it just like any built-in pipe in your template:
<p>{{ 'hello world' | capitalize }}</p>
The output will be:
Hello World
Pure vs Impure Pipes:
-
Pure pipes: These pipes only update when their input value changes (default behavior). Angular optimizes pure pipes for performance, ensuring they are recalculated only when necessary.
-
Impure pipes: These pipes are recalculated every time Angular checks for changes, regardless of whether the input value has changed. Impure pipes are typically used when the data to be transformed comes from an external source or is updated frequently (e.g., time-dependent data or user-triggered updates).
How to Create an Impure Pipe:
You can make a pipe impure by setting the pure
property to false
in the @Pipe
decorator:
@Pipe({
name: 'impurePipe',
pure: false // Makes the pipe impure
})
export class ImpurePipe implements PipeTransform {
transform(value: any): any {
// Custom transformation logic
return value;
}
}
Performance Considerations:
- Pure Pipes: These are more performance-friendly because Angular only executes them when the input data changes.
- Impure Pipes: These are less performant because they run more frequently, regardless of whether the input has changed.
For most use cases, it’s recommended to stick with pure pipes, unless you have a specific use case that requires an impure pipe (e.g., handling frequent data changes that are not bound to Angular’s change detection).
Summary of Angular Pipes Usage:
- Purpose: Pipes transform data in templates for better presentation (e.g., formatting dates, filtering lists).
- Built-in pipes: Angular provides several useful built-in pipes like
date
,currency
,uppercase
, andjson
. - Custom pipes: You can create your own pipes by implementing the
PipeTransform
interface and using the@Pipe
decorator. - Pure vs impure pipes: By default, pipes are pure, meaning they only update when input changes. Impure pipes recalculate on every change detection cycle.
Pipes in Angular are a great way to apply reusable, declarative transformations to data in the UI layer, keeping components and templates clean and maintainable.
Read More
If you can’t get enough from this article, Aihirely has plenty more related information, such as Angular interview questions, Angular interview experiences, and details about various Angular job positions. Click here to check it out.
Tags
- Angular
- AngularJS
- Angular modules
- Angular components
- Angular data binding
- Angular dependency injection
- Angular directives
- Angular RxJS
- Angular forms
- Template driven forms
- Reactive forms
- Angular CLI
- Angular routing
- Angular services
- Angular change detection
- Angular lifecycle
- Angular observables
- Angular HTTP requests
- Angular pipes
- Angular lazy loading
- NgRx
- State management in Angular
- Angular performance optimization
- Angular routing guards
- Angular lifecycle hooks
- Angular HTTPClient
- Angular observables operators
- Angular RxJS operators
- Angular HTTP error handling