diff --git a/.gitignore b/.gitignore
index ad18012f1..cad0abc01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,5 @@ Thumbs.db
TODO.md
.nx/cache
.nx/workspace-data
+
+.cursorrules
\ No newline at end of file
diff --git a/apps/signal/43-signal-input/src/app/app.component.ts b/apps/signal/43-signal-input/src/app/app.component.ts
index 22e64386e..73464303c 100644
--- a/apps/signal/43-signal-input/src/app/app.component.ts
+++ b/apps/signal/43-signal-input/src/app/app.component.ts
@@ -1,17 +1,18 @@
-import { JsonPipe } from '@angular/common';
-import { Component } from '@angular/core';
+import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { UserComponent } from './user.component';
@Component({
standalone: true,
- imports: [UserComponent, JsonPipe],
+ imports: [UserComponent],
selector: 'app-root',
+ changeDetection: ChangeDetectionStrategy.OnPush,
template: `
- @if (showUser && !!name.value) {
+
+ @if (showUser() && !!name.value) {
{
- if (age < 10) return 'Youth';
- else if (age < 18) return 'Junior';
- else if (age < 35) return 'Open';
- return 'Senior';
-};
+import { ageToCategory } from './utils';
@Component({
selector: 'app-user',
standalone: true,
imports: [TitleCasePipe],
template: `
- {{ fullName | titlecase }} plays tennis in the {{ category }} category!!
+ {{ fullName() | titlecase }} plays tennis in the {{ category() }} category!
`,
host: {
class: 'text-xl text-green-800',
},
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class UserComponent implements OnChanges {
- @Input({ required: true }) name!: string;
- @Input() lastName?: string;
- @Input() age?: string;
-
- fullName = '';
- category: Category = 'Junior';
+export class UserComponent {
+ readonly name = input.required();
+ readonly lastName = input('');
+ readonly age = input('');
- ngOnChanges(): void {
- this.fullName = `${this.name} ${this.lastName ?? ''}`;
- this.category = ageToCategory(Number(this.age) ?? 0);
- }
+ readonly fullName = computed(() => `${this.name()} ${this.lastName() ?? ''}`);
+ readonly category = computed(() => ageToCategory(Number(this.age()) ?? 0));
}
diff --git a/apps/signal/43-signal-input/src/app/utils.ts b/apps/signal/43-signal-input/src/app/utils.ts
new file mode 100644
index 000000000..c96ece45b
--- /dev/null
+++ b/apps/signal/43-signal-input/src/app/utils.ts
@@ -0,0 +1,19 @@
+import { Category } from './models';
+
+export const ageToCategory = (age: number): Category => {
+ if (age < 0 || !Number.isInteger(age)) {
+ throw new Error('Age must be a positive integer');
+ }
+
+ const categoryRanges: { [key: number]: Category } = {
+ 10: 'Youth',
+ 18: 'Junior',
+ 35: 'Open',
+ };
+
+ const threshold = Object.keys(categoryRanges)
+ .map(Number)
+ .find((limit) => age < limit);
+
+ return threshold ? categoryRanges[threshold] : 'Senior';
+};
diff --git a/apps/signal/43-signal-input/src/main.ts b/apps/signal/43-signal-input/src/main.ts
index f3a7223da..31c5da482 100644
--- a/apps/signal/43-signal-input/src/main.ts
+++ b/apps/signal/43-signal-input/src/main.ts
@@ -1,7 +1,4 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
-import { appConfig } from './app/app.config';
-bootstrapApplication(AppComponent, appConfig).catch((err) =>
- console.error(err),
-);
+bootstrapApplication(AppComponent).catch((err) => console.error(err));