Generics let you write flexible Angular services that work with different data types without repeating code.
Generics in Angular services
export class DataService<T> { private data: T[] = []; add(item: T): void { this.data.push(item); } getAll(): T[] { return this.data; } }
The <T> after the class name means this service uses a generic type called T.
You can replace T with any type when you use the service, like DataService<User>.
T from an API.import { Observable } from 'rxjs'; export class ApiService<T> { fetchAll(): Observable<T[]> { // fetch data logic return new Observable<T[]>(); } }
T.export class StorageService<T> { private items: T[] = []; save(item: T): void { this.items.push(item); } getItems(): T[] { return this.items; } }
This Angular service uses generics to store and retrieve different types of data. We create one service instance for users and another for products. Each stores its own type safely.
import { Injectable } from '@angular/core'; interface User { id: number; name: string; } interface Product { id: number; title: string; } @Injectable({ providedIn: 'root' }) export class GenericService<T> { private items: T[] = []; add(item: T): void { this.items.push(item); } getAll(): T[] { return this.items; } } // Usage example const userService = new GenericService<User>(); userService.add({ id: 1, name: 'Alice' }); userService.add({ id: 2, name: 'Bob' }); const productService = new GenericService<Product>(); productService.add({ id: 101, title: 'Book' }); console.log(userService.getAll()); console.log(productService.getAll());
Remember to specify the type when creating the service instance, like new GenericService<User>().
Generics help catch type errors early, making your code safer and easier to maintain.
Generics let Angular services work with any data type without rewriting code.
Use <T> to define a generic type placeholder in your service.
Specify the actual type when you create the service to get type safety and flexibility.
Practice
<T> in Angular services?Solution
Step 1: Understand the role of generics in Angular services
Generics use<T>as a placeholder to allow services to handle different data types flexibly.Step 2: Identify the benefit of this flexibility
This flexibility means you don't have to rewrite the service for each data type, saving time and effort.Final Answer:
It allows the service to work with any data type without rewriting code. -> Option AQuick Check:
Generics = Flexible data types [OK]
- Thinking generics improve speed
- Believing generics auto-create UI
- Assuming generics limit data types
Solution
Step 1: Recall the syntax for generic class declaration in TypeScript
The correct syntax uses angle brackets after the class name with a type parameter, likeclass ClassName<T>.Step 2: Match the syntax to Angular service class
export class DataService<T> { } correctly showsexport class DataService<T> { }, which is valid for a generic service.Final Answer:
export class DataService<T> { } -> Option AQuick Check:
Generic class syntax = class Name<T> [OK]
- Adding parentheses after <T>
- Using 'extends' without a type
- Using arrow functions for class declaration
export class DataService<T> {
private items: T[] = [];
add(item: T) { this.items.push(item); }
getAll(): T[] { return this.items; }
}
const service = new DataService<string>();
service.add('hello');
service.add('world');
console.log(service.getAll());What will be logged to the console?
Solution
Step 1: Understand the generic type used
The service is created withstringas the type, soitemsis an array of strings.Step 2: Trace the add and getAll methods
Two strings 'hello' and 'world' are added, thengetAll()returns the array with these two strings.Final Answer:
['hello', 'world'] -> Option DQuick Check:
Generic array with strings = ['hello', 'world'] [OK]
- Thinking output is unquoted strings
- Expecting extra undefined elements
- Assuming type errors at runtime
export class DataService<T> {
private items: T[] = [];
add(item: T) { this.items.push(item); }
getAll(): T[] { return this.items; }
}
const service = new DataService();
service.add(123);Solution
Step 1: Check service instantiation
The service is created without specifying the generic type<T>, so TypeScript cannot infer the type.Step 2: Understand consequences of missing generic type
Without the type, the compiler may treatTasanyor cause errors, losing type safety.Final Answer:
Missing generic type argument when creating service instance. -> Option CQuick Check:
Always specify <T> when creating generic service [OK]
- Ignoring missing generic type argument
- Thinking private properties cause errors
- Expecting getAll() to return Promise
Solution
Step 1: Understand Angular HttpClient generic method
HttpClient'sget<T>method allows specifying the expected data type for the response.Step 2: Ensure type safety by specifying
By usingTwhen callingget<T>(url), the returned Observable emits data typed asT, ensuring compile-time checks.Final Answer:
Useget<T>(url: string): Observable<T>in the service method and specify type when calling. -> Option BQuick Check:
HttpClient generics = type-safe API calls [OK]
- Using any instead of generics loses type safety
- Casting manually after subscription is error-prone
- Returning Observable<string> ignores actual data shape
Ready to prove it?
Pass the test and this pattern moves unknown
