Angular Architecture Explained

Overview

Angular follows a component-based architecture that promotes modularity, maintainability, and scalability. Here’s a comprehensive overview of Angular’s architecture:

Angular Architecture Overview

1. Components and Templates

Components are the fundamental building blocks of Angular applications. They consist of:

// Component Definition
@Component({
  selector: 'app-user-profile',
  template: `
    <div class="profile">
      <h2>{{ user.name }}</h2>
      <p>{{ user.bio }}</p>
      <button (click)="updateProfile()">Update</button>
    </div>
  `,
  styles: [`
    .profile {
      padding: 1rem;
      border: 1px solid #ddd;
    }
  `]
})
export class UserProfileComponent {
  @Input() user: User;
  @Output() update = new EventEmitter<User>();

  updateProfile() {
    this.update.emit(this.user);
  }
}

Component Tree Structure

Components in Angular form a tree structure, with the AppComponent at the root:

Component Tree Structure

2. Modules

Modules in Angular help organize the application into cohesive blocks of functionality:

@NgModule({
  declarations: [
    UserProfileComponent,
    UserListComponent
  ],
  imports: [
    CommonModule,
    SharedModule,
    UserRoutingModule
  ],
  providers: [
    UserService,
    { provide: API_URL, useValue: 'https://api.example.com' }
  ],
  exports: [UserProfileComponent]
})
export class UserModule { }

Module Types:

  1. Root Module (AppModule)

    • Bootstrap component
    • Core services
    • App-wide providers
  2. Feature Modules

    • Domain-specific functionality
    • Lazy loading support
    • Encapsulated components
  3. Shared Modules

    • Reusable components
    • Common directives
    • Pipes

3. Dependency Injection (DI)

Angular’s DI system is hierarchical and follows the component tree:

Dependency Injection Flow

// Service with DI
@Injectable({
  providedIn: 'root'  // Application-wide singleton
})
export class DataService {
  constructor(
    private http: HttpClient,
    @Inject(API_URL) private apiUrl: string
  ) {}

  getData(): Observable<any> {
    return this.http.get(`${this.apiUrl}/data`);
  }
}

// Component using the service
@Component({
  providers: [
    // Component-level provider
    { provide: DataService, useClass: MockDataService }
  ]
})
export class DataComponent {
  constructor(private dataService: DataService) {}
}

4. Data Flow and Change Detection

Angular uses a unidirectional data flow and Zone.js for change detection:

@Component({
  selector: 'app-parent',
  template: `
    <app-child
      [data]="parentData"
      (update)="onUpdate($event)">
    </app-child>
  `
})
export class ParentComponent {
  parentData = { value: 'initial' };

  onUpdate(newValue: string) {
    this.parentData = { value: newValue };
  }
}

@Component({
  selector: 'app-child',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div>{{ data.value }}</div>
    <button (click)="updateValue()">Update</button>
  `
})
export class ChildComponent {
  @Input() data: { value: string };
  @Output() update = new EventEmitter<string>();

  updateValue() {
    this.update.emit('new value');
  }
}

5. Services and State Management

Services manage data, state, and business logic:

// State Management Service
@Injectable({
  providedIn: 'root'
})
export class StateService {
  private state = new BehaviorSubject<AppState>(initialState);
  
  // Expose state as observable
  state$ = this.state.asObservable();

  // Update state
  updateState(newState: Partial<AppState>) {
    this.state.next({
      ...this.state.value,
      ...newState
    });
  }

  // Select specific state slice
  select<T>(selector: (state: AppState) => T): Observable<T> {
    return this.state$.pipe(
      map(selector),
      distinctUntilChanged()
    );
  }
}

6. Routing and Navigation

Angular’s router enables navigation and lazy loading:

const routes: Routes = [
  {
    path: 'users',
    component: UserListComponent,
    children: [
      {
        path: ':id',
        component: UserDetailComponent,
        resolve: {
          user: UserResolver
        }
      }
    ],
    canActivate: [AuthGuard]
  },
  {
    path: 'admin',
    loadChildren: () => 
      import('./admin/admin.module').then(m => m.AdminModule),
    canLoad: [AdminGuard]
  }
];

// Router Service Usage
@Injectable()
export class NavigationService {
  constructor(
    private router: Router,
    private location: Location
  ) {}

  navigateToUser(id: string) {
    this.router.navigate(['/users', id], {
      queryParams: { view: 'details' }
    });
  }

  goBack() {
    this.location.back();
  }
}

7. HTTP and Backend Communication

Angular’s HttpClient handles API communication:

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  constructor(
    private http: HttpClient,
    private errorHandler: ErrorHandlingService
  ) {}

  getData<T>(endpoint: string): Observable<T> {
    return this.http.get<T>(`${this.apiUrl}/${endpoint}`).pipe(
      retry(3),
      catchError(error => this.errorHandler.handle(error))
    );
  }

  postData<T>(endpoint: string, data: any): Observable<T> {
    return this.http.post<T>(`${this.apiUrl}/${endpoint}`, data).pipe(
      catchError(error => this.errorHandler.handle(error))
    );
  }
}

Interview Tips

When discussing Angular’s architecture in interviews:

  1. Emphasize Modularity

    • Explain how components, modules, and services promote clean code
    • Discuss how DI enables testing and maintainability
  2. Performance Considerations

    • Change detection strategies
    • Lazy loading
    • State management patterns
  3. Best Practices

    • Smart vs. Presentational components
    • Service organization
    • Module structure
  4. Real-world Examples

    • Share experiences with large-scale applications
    • Discuss architectural decisions and trade-offs
    • Explain how Angular’s architecture solves common problems

Test Your Knowledge

Take a quick quiz to test your understanding of this topic.

Test Your Angular Knowledge

Ready to put your skills to the test? Take our interactive Angular quiz and get instant feedback on your answers.