$30 off During Our Annual Pro Sale. View Details »

Lightweight Architectures With Angular's Latest Innovations

Lightweight Architectures With Angular's Latest Innovations

Manfred Steyer
PRO

June 13, 2023
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. @ManfredSteyer
    Lightweight Architectures
    With Angular's Latest Innovations
    ManfredSteyer

    View Slide

  2. @ManfredSteyer

    View Slide

  3. @ManfredSteyer

    View Slide

  4. @ManfredSteyer

    View Slide

  5. @ManfredSteyer

    View Slide

  6. @ManfredSteyer

    View Slide

  7. @ManfredSteyer
    Manfred Steyer

    View Slide

  8. @ManfredSteyer

    View Slide

  9. @ManfredSteyer
    NgModules + EcmaScript Modules
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { AppComponent } from './app.component';
    […]
    @NgModule({
    imports: [BrowserModule, OtherModule],
    declarations: [AppComponent, OtherComponent, OtherDirective],
    providers: [],
    bootstrap: [AppComponent],
    })
    export class AppModule {}
    TypeScript Modules
    Angular Modules

    View Slide

  10. @ManfredSteyer
    @Component({
    standalone: true,
    imports: [
    […],
    FlightCardComponent,
    CityPipe,
    CityValidator,
    ],
    selector: 'flight-search',
    templateUrl: '…'
    })
    export class FlightSearchComponent {
    […]
    }

    View Slide

  11. @ManfredSteyer

    View Slide

  12. @ManfredSteyer
    Small and Medium Apps:
    Folder per Feature

    View Slide

  13. @ManfredSteyer
    Medium and Large Apps:
    Folder per Domain

    View Slide

  14. @ManfredSteyer
    Restricting Access b/w Domains, etc.
    on a library basis

    View Slide

  15. @ManfredSteyer
    Restricting Access b/w Domains, etc.
    on a folder basis
    Credits to:
    Rainer Hahnekamp,
    AngularArchitects
    @softarc/eslint-plugin-sheriff

    View Slide

  16. @ManfredSteyer

    View Slide

  17. @ManfredSteyer

    View Slide

  18. @ManfredSteyer
    bootstrapApplication(AppComponent, {
    providers: [
    provideHttpClient(
    withInterceptors([authInterceptor]),
    ),
    provideRouter(APP_ROUTES,
    withPreloading(PreloadAllModules),
    withDebugTracing(),
    ),
    ]
    });

    View Slide

  19. @ManfredSteyer
    bootstrapApplication(AppComponent, {
    providers: [
    provideLogger(loggerConfig,
    withColor({ debug: 3 })
    ),
    ]
    });

    View Slide

  20. @ManfredSteyer

    View Slide

  21. @ManfredSteyer
    bootstrapApplication(AppComponent, {
    providers: [
    provideLogger(loggerConfig,
    withColor({ debug: 3 })
    ),
    ]
    });

    View Slide

  22. @ManfredSteyer
    export function provideLogger(config: LoggerConfig): Provider[] {
    […]
    }

    View Slide

  23. @ManfredSteyer
    export function provideLogger(config: LoggerConfig): Provider[] {
    return [
    LoggerService,
    {
    provide: LoggerConfig,
    useValue: config
    },
    {
    provide: LogFormatter,
    useValue: config.formatter
    },
    ];
    }

    View Slide

  24. @ManfredSteyer
    export function provideLogger(config: LoggerConfig): Provider[] {
    return [
    LoggerService,
    {
    provide: LoggerConfig,
    useValue: config
    },
    {
    provide: LogFormatter,
    useValue: config.formatter
    },
    ];
    }

    View Slide

  25. @ManfredSteyer
    export function provideLogger(config: LoggerConfig): EnvironmentProviders {
    return makeEnvironmentProviders([
    LoggerService,
    {
    provide: LoggerConfig,
    useValue: config
    },
    {
    provide: LogFormatter,
    useValue: config.formatter
    },
    ]);
    }

    View Slide

  26. @ManfredSteyer
    export function provideLogger(
    config: LoggerConfig, ...featues: LoggerFeature[]
    ): EnvironmentProviders {
    return makeEnvironmentProviders([
    LoggerService,
    […],
    features?.map(f => f.providers)
    ]);
    }

    View Slide

  27. @ManfredSteyer

    View Slide

  28. @ManfredSteyer

    View Slide

  29. @ManfredSteyer

    View Slide

  30. @ManfredSteyer
    @Component({ […] })
    export class FlightEditComponent {
    @Input() id = '';
    @Input() showDetails = '';
    […]
    }
    All you need for getting
    routing parameters!

    View Slide

  31. @ManfredSteyer
    bootstrapApplication(AppComponent, {
    providers: [
    […]
    provideRouter(
    APP_ROUTES,
    withComponentInputBinding(),
    ),
    […]
    }

    View Slide

  32. @ManfredSteyer
    export const APP_ROUTES: Routes = [
    {
    path: 'home',
    component: HomeComponent,
    },
    {
    path: 'flight-booking',
    loadChildren: () => import('./[…]/flight-booking.routes')
    .then(m => m.FLIGHT_BOOKING_ROUTES)
    },
    ];

    View Slide

  33. @ManfredSteyer
    export const APP_ROUTES: Routes = [
    {
    path: 'home',
    component: HomeComponent,
    },
    {
    path: 'flight-booking',
    loadChildren: () => import('./[…]/flight-booking.routes')
    .then(m => m.FLIGHT_BOOKING_ROUTES)
    },
    ];
    Lazy routing config
    as default expert

    View Slide

  34. @ManfredSteyer
    export const APP_ROUTES: Routes = [
    […]
    {
    path: 'flight-booking',
    canActivate: [() => inject(AuthService).isAuthenticated()],
    component: FlightBookingComponent
    },
    ]

    View Slide

  35. @ManfredSteyer
    export const APP_ROUTES: Routes = [
    […]
    {
    path: 'flight-booking',
    canActivate: [() => inject(AuthService).isAuthenticated()],
    component: FlightBookingComponent
    },
    ]

    View Slide

  36. @ManfredSteyer
    export const APP_ROUTES: Routes = [
    […]
    {
    path: 'flight-booking',
    canActivate: [() => inject(AuthService).isAuthenticated()],
    resolve: {
    flights: () => inject(FlightService).findAll()
    },
    component: FlightBookingComponent
    },
    ]

    View Slide

  37. @ManfredSteyer
    export const authInterceptor: HttpInterceptorFn = (req, next) => {
    […]
    }

    View Slide

  38. @ManfredSteyer
    bootstrapApplication(AppComponent, {
    providers: [
    provideHttpClient(
    withInterceptors([authInterceptor]),
    ),
    ]
    });

    View Slide

  39. @ManfredSteyer
    @Injectable({ providedIn: 'root' })
    export class FlightBookingFacade {
    private flightService = inject(FlightService);
    private _flights = signal([]);
    readonly flights = this._flights.asReadonly();
    […]
    }

    View Slide

  40. @ManfredSteyer
    @Injectable({ providedIn: 'root' })
    export class FlightBookingFacade {
    private flightService = inject(FlightService);
    private _flights = signal([]);
    readonly flights = this._flights.asReadonly();
    async load(from: string, to: string) {
    const flights = await this.flightService.findPromise(from, to);
    this._flights.set(flights);
    }
    […]
    }

    View Slide

  41. @ManfredSteyer

    View Slide

  42. @ManfredSteyer

    View Slide

  43. @ManfredSteyer
    d
    Slides & Examples Remote Company Workshops
    and Consulting
    http://angulararchitects.io

    View Slide