Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General: Bind route information to inputs #10125

Open
magaupp opened this issue Jan 10, 2025 · 0 comments
Open

General: Bind route information to inputs #10125

magaupp opened this issue Jan 10, 2025 · 0 comments
Labels
client Pull requests that update TypeScript code. (Added Automatically!) core Pull requests that affect the corresponding module exam Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module refactoring text Pull requests that affect the corresponding module

Comments

@magaupp
Copy link
Contributor

magaupp commented Jan 10, 2025

Refactoring

Context

Problem

Currently, if we wanted to use Route parameters (e.g. courseId and exerciseId from /course-management/:courseId/programming-exercises/:exerciseId) or Route data, we inject ActivatedRoute and subscribe to its params or data Observable. The Subscription has to be unsubscribed when the component is destroyed. This approach is complex and boilerplate-heavy.

Motivation

A simpler approach is to enable withComponentInputBinding(). Once enabled, input signals with a matching name can be used instead.
This is approach is recommended Angular's Route Guide and available since Angular v16.

Example

ActivatedRoute:

route = inject(ActivatedRoute);

ngOnInit() {
  this.paramsSubscription = this.route.params.subscribe((params) => {
    const exerciseId = params['exerciseId'];
    ...
  });
}

ngOnDestroy() {
  this.paramsSubscription.unsubscribe();
}

withComponentInputBinding():

exerciseId = input<number>();

constructor() {
  effect(() => {
    const exerciseId = this.exerciseId();
    ...
  });
}

Blocking Issues

To enable the feature, withComponentInputBinding() can be added to the provideRouter() call.

However, we cannot enable it without breaking existing Components. Existing Component inputs without corresponding route data will be set to undefined. If the Component does not expect undefined in its input, the Component will break.

Docs:

Importantly, when an input does not have an item in the route data with a matching key, this input is set to undefined. This prevents previous information from being retained if the data got removed from the route (i.e. if a query parameter is removed). Default values can be provided with a resolver on the route to ensure the value is always present or an input and use an input transform in the component.

Whilst Route Components cannot have required inputs (currently, inputs cannot be set via a route), the can have inputs with default values. These inputs will be set to undefined once the feature is enabled.

Example

text-editor.route.ts:

// no displayHeader
{
    path: 'participate/:participationId',
    loadComponent: () => import('./text-editor.component').then((m) => m.TextEditorComponent),
    data: {
        authorities: [Authority.USER],
        pageTitle: 'artemisApp.textExercise.home.title',
    }
}

text-editor.component.ts:

displayHeader: InputSignal<boolean> = input<boolean>(true);  // this signal will be set to undefined

The RegEx ActivatedRoute(.|\n)*?(input(<[^>]*>)\([^\)]+\)|@Input[^;]*=) finds Components with defaulted inputs in files where ActivatedRoute is imported. These Components are likely candidates for needing changes.
However, other Components used in Routes might not import ActvatedRoute.

Before the migration can be done, all affected Components need to be identified.

Components needing changes (incomplete)

Component Changed
TextEditorComponent
@magaupp magaupp added client Pull requests that update TypeScript code. (Added Automatically!) refactoring labels Jan 10, 2025
@github-actions github-actions bot added core Pull requests that affect the corresponding module exam Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module text Pull requests that affect the corresponding module labels Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client Pull requests that update TypeScript code. (Added Automatically!) core Pull requests that affect the corresponding module exam Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module refactoring text Pull requests that affect the corresponding module
Projects
None yet
Development

No branches or pull requests

1 participant