- Services: How to create and use services for data sharing and business logic.
- Dependency Injection: How DI works in Angular, providers, and the injector system.
- Singleton Services: Creating and managing singleton services.
- Service is nothing its just a class with specific purpose.
- Data Sharing Across multiple components.
- It is used to apply application logic
- We can use Services for external interactions such as connecting to a database.
- The best solution is to write services and inject in application where we need it.
- Services are usually implemented through dependency injection.
- Organize and share business logic, models or data and functions with different components in angular application
- As we all know that Angular uses the concept of components.
- The Entire Ul of the Angular application is divided into several
- components.
- Sometimes all these components performing common tasks like displaying images on the view, accessing the database etc
To avoid writing code again and again, Angular Services comes into place.
These services can then be injected into the components that require that service or dependency.
The main objective of a service is to organize and share business logic, models, or data and functions with different components of an Angular application.
Services are piece of code that are used to perform a specific task, a service can contain a value or function or combination of both.
Services prevent us from writing same code at multiple sections of our application.
The best solution is to write services and inject in application where we need it.
Services are usually implemented through dependency injection.
Dependency Injection
Dependency Injection is a coding pattern in which a class receives its dependencies from external sources rather than creating them itself.
- Create service
- Register with injector
Use this command to generate the service:
ng g s services/studentService
Injectable decorator (@Injectable
) → injectable services
@Injectable({
providedIn: 'root'
})
export class StudentServiceService {
constructor() { }
}
DI as a design pattern → in which class receives its dependency from external sources rather than creating them itself
1.studentservice
export class StudentServiceService {
constructor() { }
getStudent(){
return [
{name: "Ram", age: 21, class: 11},
{name: "Sia", age: 22, class: 12},
{name: "Sita", age: 23, class: 13},
]
}
}
2.Register with injector
@Component({
selector: 'app-first',
templateUrl: './first.component.html',
styleUrls: ['./first.component.css'],
providers: [StudentService]
})
export class FirstComponent {
public students: any;
constructor(private std: StudentService) {
this.students = std.getStudent();
console.log(this.students);
}
}
💡 Two ways register the services
- App level ( app.module.ts )
- component level
You can add that in app.module.ts file - globally inject the service.
import { StudentService } from './services/student.service';
@NgModule({
declarations: [],
imports: [],
providers: [StudentService],
bootstrap: []
})
export class AppModule { }
Fetching And Displaying API Data
-
What is an API?
- An API (Application Programming Interface) acts as a bridge between applications and databases, enabling them to interact.
- APIs support different formats like JSON (commonly used for being lightweight) and XML for data transfer.
-
Understanding API Usage in Applications:
- APIs can be used across mobile, desktop, and web applications, as well as IoT devices.
- They handle operations such as data retrieval, insertion, updates, and deletion, utilizing HTTP protocols (GET, POST, PUT, DELETE).
-
Real-life Examples of APIs:
- APIs for weather updates, payment systems (e.g., PayPal, Paytm), and healthcare data (e.g., COVID-19 case statistics).
- These demonstrate the power of APIs in sharing and managing data across platforms.
-
API Implementation in Angular:
- Angular uses services to make API calls, where the HTTP Client Module facilitates communication with APIs.
- The process involves creating a service that interacts with the API and connects it to Angular components.
-
Practical Demonstration Goals:
- Explanation of HTTP Client Module and how it works in Angular.
- Implementation of a service to fetch data from an API and display it in an Angular application.
- Key prerequisites include understanding services and dependency injection, as covered in previous lectures.
Key Flow in Angular:
- Create an Angular component where data is displayed.
- Create a service to handle API interactions using the HTTP Client Module.
- Link the service with the component to fetch and display the data from the API.
HTTP Verbs
- GET
- POST
- PUT
- DELETE
Angular app → service → APIcall → database
component → service → HTTP module → API server
API ↔ Service ←—Subscribe-—— component
1. Setting Up the Angular Project
Before fetching data, ensure your Angular project is ready. If not, create a new Angular application using:
ng new my-angular-app
cd my-angular-app
Once done, open your project in Visual Studio Code and install all dependencies using:
npm install
2. Importing HttpClientModule
To interact with APIs, Angular provides the HttpClientModule
. Import it in your app.module.ts
file as follows:
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
This allows Angular to make HTTP requests.
3. Creating a Service for API Interaction
Services in Angular handle logic that can be reused across components. Create a service using:
ng generate service services/post
This command creates a services
folder with post.service.ts
and post.service.spec.ts
. Open post.service.ts
and update it:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class PostService {
private url: string = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) {}
getPosts(): Observable<any> {
return this.http.get(this.url);
}
}
Here:
- The
getPosts()
method fetches data from the API.
4. Injecting the Service into a Component
To use the service, inject it into a component. Open app.component.ts
and modify it:
import { Component, OnInit } from '@angular/core';
import { PostService } from './services/post.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
posts: any[] = [];
constructor(private postService: PostService) {}
ngOnInit(): void {
this.postService.getPosts().subscribe(
(data) => {
this.posts = data;
},
(error) => {
console.error('Error fetching posts', error);
}
);
}
}
5. Displaying Data in the Template
Update app.component.html
to display the fetched data:
<div *ngIf="posts.length > 0; else noData">
<h2>Posts</h2>
<ul>
<li *ngFor="let post of posts">
<h3>{{ post.title }}</h3>
<p>{{ post.body }}</p>
</li>
</ul>
</div>
<ng-template #noData>
<p>No posts available.</p>
</ng-template>
This uses Angular's *ngFor
directive to iterate over and display each post.
6. Understanding the API Response
The API returns a JSON array of posts, each containing properties like userId
, id
, title
, and body
. You can preview this data in your browser by visiting https://jsonplaceholder.typicode.com/posts
.
7. Enhancing Error Handling
Add error handling in the service for robustness. Update the getPosts()
method:
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
getPosts(): Observable<any> {
return this.http.get(this.url).pipe(
catchError((error) => {
console.error('Error occurred:', error);
return throwError(error);
})
);
}
8. Styling the Data
Update app.component.css
to style the posts:
h2 {
text-align: center;
color: #4caf50;
}
li {
list-style: none;
margin: 10px 0;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
h3 {
margin: 0;
color: #333;
}
p {
color: #555;
}
9. Running the Application
Run the Angular application using:
ng serve
Open the browser at http://localhost:4200
to see your application fetching and displaying posts.
Singleton Services in Angular: Creating and Managing Shared Services
In Angular, services are used to encapsulate reusable logic, data sharing, and communication between components. A singleton service is a service that is instantiated once and shared across the application, ensuring a single source of truth and efficient resource management.
This blog explores how to create and manage singleton services effectively in Angular.
What is a Singleton Service?
A singleton service is a service instance that is shared across the entire application. Angular ensures that only one instance of the service exists throughout the application lifecycle, which can be crucial for scenarios like managing global state or shared resources.
How to Create a Singleton Service
1. Use @Injectable
with providedIn: 'root'
Angular provides the @Injectable
decorator to make a service injectable. Setting providedIn: 'root'
registers the service in the root injector, making it a singleton.
Example: Singleton Service
my-service.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Registers this service as a singleton
})
export class MyService {
private counter = 0;
increment() {
this.counter++;
}
getCount(): number {
return this.counter;
}
}
2. Provide the Service in AppModule
Alternatively, you can declare a singleton service in the root module's providers
array.
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyService } from './my-service.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [MyService], // Singleton service
bootstrap: [AppComponent]
})
export class AppModule {}
Using the Singleton Service
You can inject the singleton service into any component or another service to share its functionality and state.
app.component.ts
import { Component } from '@angular/core';
import { MyService } from './my-service.service';
@Component({
selector: 'app-root',
template: `
<button (click)="increment()">Increment</button>
<p>Counter: {{ count }}</p>
`
})
export class AppComponent {
count: number = 0;
constructor(private myService: MyService) {}
increment() {
this.myService.increment();
this.count = this.myService.getCount();
}
}
child.component.ts
import { Component } from '@angular/core';
import { MyService } from './my-service.service';
@Component({
selector: 'app-child',
template: `<p>Shared Counter: {{ count }}</p>`
})
export class ChildComponent {
count: number;
constructor(private myService: MyService) {
this.count = this.myService.getCount();
}
}
Both AppComponent
and ChildComponent
will share the same instance of MyService
, ensuring a consistent counter value.
Best Practices for Singleton Services
-
Use
providedIn: 'root'
- Recommended for most singleton services as it simplifies registration and tree-shaking.
-
Avoid Stateful Services When Possible
- Stateful singleton services can introduce hard-to-track bugs. Use them only when necessary.
-
Lazy Initialization
- Initialize resource-heavy services only when needed to reduce application startup time.
-
Thread-Safe Design
- Ensure thread-safe access to shared resources in services, especially in multi-threaded environments.
When to Use Singleton Services
-
State Management
- Managing global states like user authentication or preferences.
-
Shared Resources
- Services for shared resources like HTTP clients, configuration data, or caching.
-
Cross-Component Communication
- Facilitating communication between unrelated components.
Conclusion
Singleton services are a cornerstone of Angular's dependency injection system. By leveraging a single instance across your application, you can simplify data sharing, improve performance, and maintain consistent application state. Understanding how to create and manage singleton services is essential for building scalable and efficient Angular applications.
Have any unique use cases or challenges with singleton services? Let us know in the comments!
You can see these blogs to cover all angular concepts:
Beginner's Roadmap: Your Guide to Starting with Angular
- Core Angular Concepts
- Services and Dependency Injection
- Routing and Navigation
- Forms in Angular
- RxJS and Observables
- State Management
- Performance Optimization
Happy coding!
Top comments (1)
Hi Renuka Patil,
Very nice and helpful !
Thanks for sharing.