Date:

Angular Tips #3

Using the Abstract Class to Define Services Includes Things in Common

Abstract classes are very powerful in TypeScript and extremely useful when working with Angular. They help enforce structure, promote reusability, and keep your codebase clean and maintainable.

In Angular, there are scenarios where you need to define multiple services that share many common functionalities. In such cases, you can use an abstract class as a base service to inherit and centralize shared logic across different services.

For example, I have two services: book.service.ts and music.service.ts. They are defined as follows:

// Book service
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

type Book = {
  readonly name: string;
  readonly author: string;
};

@Injectable({
  providedIn: 'root'
})
export class BookService {
  protected readonly page$: Observable<Book[]>;

  protected getBooks(): Observable<Book[]> {
    return of([{ name: 'Book 1', author: 'Conan' });
  }

  protected resetBooks(): Observable<Book[]> {
    return of([]);
  }

  constructor() {
    this.page$ = this.getBooks();
  }
}
// Music service
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MusicService extends BaseService {
  protected getList(): Observable<Music[]> {
    return of([{ name: 'Music 1', artist: 'Edward' });
  }
}

As you can see, we only need to redefine the abstract getList() function in each service. Everything else is inherited from the base service, making our code cleaner, more maintainable, and reusable.

Implement Lazy Loading for Optimizing Application Performance, but be Careful

Lazy loading in Angular is a technique used to load feature modules only when needed, reducing the initial bundle size and improving application performance. Instead of loading all modules upfront, Angular loads them dynamically when a user navigates to a specific route.

We can define a lazy load module, like this:

const routes: Routes = [
  {
    path: 'feature',
    loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
  }
];

However, this is not always the case where lazy load comes to the rescue. With lazy load, it will load the module only when it’s needed, which means, as a traceback, the loading time in the first visit of the component require that module will be increased.

When Lazy Loading Can Hurt UX:

  • Heavy Pages: If a page has a large bundle size, lazy loading can introduce a noticeable delay, making users think the app is slow or broken.
  • Frequent Navigation: If users frequently switch between pages, repeatedly loading modules can be inefficient.
  • Above-the-Fold Content: If a page requires immediate rendering of essential content, lazy loading might cause delays.

So, to use lazy loading efficiently, let’s combine it with preloadStrategies. To dive deeper into preloadStrategies in Angular, I recommend checking out the blog: Optimize your Angular app’s user experience with preloading strategies. This resource is extremely useful for understanding how to choose the right preloadStrategies for your app.

Conclusion

And that’s all for blog #3 about the Angular tips! I hope you found these tips helpful. See you in my next blog!

FAQs

Q: What is the benefit of using abstract classes in Angular?
A: Abstract classes help enforce structure, promote reusability, and keep your codebase clean and maintainable.

Q: What is lazy loading in Angular?
A: Lazy loading is a technique used to load feature modules only when needed, reducing the initial bundle size and improving application performance.

Q: When should I use lazy loading?
A: Use lazy loading when you need to load feature modules only when needed, reducing the initial bundle size and improving application performance.

Q: What are the potential issues with lazy loading?
A: Heavy pages, frequent navigation, and above-the-fold content can be affected by lazy loading, introducing noticeable delays and inefficiencies.

Latest stories

Read More

LEAVE A REPLY

Please enter your comment!
Please enter your name here