Advanced Angular Patterns: RxJS, State Management & Performance
Advanced Angular Patterns
Angular is a powerful framework for building enterprise applications. Let's explore advanced patterns and best practices.
RxJS Mastery
Operators You Should Know
```typescript
import { map, filter, switchMap, debounceTime, distinctUntilChanged } from 'rxjs/operators';
// Search with debounce
searchTerm$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => this.searchService.search(term))
).subscribe(results => {
this.results = results;
});
```Common Patterns
1. **switchMap**: Cancel previous requests
2. **combineLatest**: Combine multiple observables
3. **forkJoin**: Wait for all observables to complete
4. **shareReplay**: Share and cache results
State Management
NgRx (Redux Pattern)
```typescript
// Actions
export const loadUsers = createAction('[User] Load Users');
export const loadUsersSuccess = createAction(
'[User] Load Users Success',
props<{ users: User[] }>()
);
// Reducer
export const userReducer = createReducer(
initialState,
on(loadUsers, state => ({ ...state, loading: true })),
on(loadUsersSuccess, (state, { users }) => ({
...state,
users,
loading: false
}))
);
// Effects
@Injectable()
export class UserEffects {
loadUsers$ = createEffect(() =>
this.actions$.pipe(
ofType(loadUsers),
switchMap(() =>
this.userService.getUsers().pipe(
map(users => loadUsersSuccess({ users }))
)
)
)
);
}
```Akita (Simplified State Management)
Akita provides a simpler alternative to NgRx:
- Less boilerplate
- Built-in dev tools
- Entity management
Performance Optimization
1. OnPush Change Detection
```typescript
@Component({
selector: 'app-user-list',
templateUrl: './user-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserListComponent {
@Input() users: User[];
}
```2. TrackBy Functions
```typescript
trackByUserId(index: number, user: User): number {
return user.id;
}
```3. Lazy Loading Modules
```typescript
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module')
.then(m => m.AdminModule)
}
];
```Advanced Component Patterns
1. Smart vs Dumb Components
- Smart components manage state
- Dumb components receive inputs and emit outputs
2. Content Projection
Use `
3. Dynamic Components
Load components dynamically using ComponentFactoryResolver.
Testing Best Practices
```typescript
describe('UserComponent', () => {
let component: UserComponent;
let fixture: ComponentFixture
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [UserComponent],
imports: [HttpClientTestingModule]
});
fixture = TestBed.createComponent(UserComponent);
component = fixture.componentInstance;
});
it('should load users on init', () => {
component.ngOnInit();
expect(component.users.length).toBeGreaterThan(0);
});
});
```Conclusion
Mastering these advanced Angular patterns will help you build scalable, performant, and maintainable applications. Focus on reactive programming with RxJS, proper state management, and performance optimization techniques.