feat: improve docs

This commit is contained in:
thomas
2023-12-16 15:59:24 +01:00
parent 99c9bd464e
commit d2035864ec
27 changed files with 34 additions and 125 deletions

View File

@@ -16,10 +16,12 @@ jobs:
days-before-issue-close: -1
stale-issue-label: 'stale'
stale-issue-message: 'This issue is stale because it has been open for 20 days with no activity.'
exempt-issue-labels: 'long-term'
days-before-pr-stale: 20
days-before-pr-close: 7
stale-pr-label: 'stale'
stale-pr-message: 'This pull request is stale because it has been open for 20 days with no activity.'
close-pr-message: 'This pull request was closed because it has been inactive for 7 days since being marked as stale.'
only-pr-labels: 'answer'
exempt-pr-labels: 'challenge-creation, long-term'
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -8,11 +8,7 @@ sidebar:
order: 202
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
The goal of this series of 3 pipe challenges is to master PIPES in Angular.
The goal of this series of 3 pipe challenges is to master **pipe** in Angular.
Pure pipes are a very useful way to transform data from your template. The difference between calling a function and a pipe is that pure pipes are memoized. So they won't be recalculated every change detection cycle if their inputs haven't changed.

View File

@@ -8,13 +8,9 @@ sidebar:
order: 104
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Styling is an important aspect of a frontend developer's day job, but it is often underestimated. In Angular applications, I frequently see people using `@Input()` to customize the style of their components. However, `@Input()` should only be used for logic; and other techniques, such as CSS variables and host-context, should be used for styling.
Styling is an important aspect of a frontend developer's day job, but it is often underestimated. In Angular applications, I frequently see people using `@Input()` to customize the style of their components. However, `@Input()` should only be used for logic. Other techniques, such as **CSS variables** and **host-context** should be used for styling.
In this challenge, you will need to use both CSS variables and `:host-context` to remove all `@Input()` from your code.

View File

@@ -8,17 +8,13 @@ sidebar:
order: 203
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
To successfully complete this challenge, you will need to have a good understanding of how Dependency Injection works inside Angular.
The goal is to provide the CurrencyService at the row level, so that each row displays the correct currency. Currently, the CurrencyService is only provided at the table level, which results in an error as the same currency is displayed for each row, despite each product having a different currency.
The goal is to provide the `CurrencyService` at the row level, so that each row displays the correct currency. Currently, the `CurrencyService` is only provided at the table level, which results in an error as the same currency is displayed for each row, despite each product having a different currency.
One way to achieve this is by adding a second argument to the pipe, but this is not allowed.
One way to achieve this is by adding a second argument to the pipe, but this is not allowed for this challenge.
## Statement

View File

@@ -8,10 +8,6 @@ sidebar:
order: 4
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
You begin with an application that has basic navigation and anchor navigation in the `HomeComponent`. However, using `href` recreates the path each time and refreshes the page.

View File

@@ -10,7 +10,7 @@ sidebar:
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
This exercice can feel obsolete with the new control flow and the empty block inside the `@for` block. However **structural directives** are not going to be deleted any time soon, so you can still learn a lot from this exercice.
:::
## Information

View File

@@ -8,14 +8,12 @@ sidebar:
order: 204
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
<div class="chip">Challenge #30</div>
## Information
In this challenge, we have a small reactive application using RxJS and NgRx/Component-Store.
In this challenge, we have a small reactive application using **RxJS** and **NgRx/Component-Store**.
The goal of this challenge is to use the new **Signal API** introduced in Angular v16. However, we should not convert everything. Certain portions of the code are better suited for RxJS rather than Signal. It is up to you to determine the threshold and observe how **Signal and RxJS coexist**, as well as how the interoperability is achieved in Angular.
## Note
- You can use any third party library if you want to like **ngrx/signal-store**, **tanstack-query** or **rxAngular**.

View File

@@ -8,20 +8,20 @@ sidebar:
order: 6
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
In v14, standalone components were released and made stable in v15. If you haven't played with them, it's never too late. You can try them out in this challenge.
Moreover, the goal is to see how Nx and standalone components work together, and experience the process of decoupling your app with Nx lib and standalone components.
Moreover, the goal is to see how **Nx** and **standalone components** work together, and experience the process of decoupling your app with Nx lib and standalone components.
Finally, standalone components are very simple to understand, but routing/lazy-loaded components can be a bit harder to grasp. This challenge will allow you to manipulate components at different levels of nesting and work with lazy loaded routes.
Finally, standalone components are very simple to understand, but **routing/lazy-loaded components** can be a bit harder to grasp. This challenge will allow you to manipulate components at different levels of nesting and work with lazy loaded routes.
After completing this challenge, standalone components will no longer hold any secrets for you.
## Statement
The goal of this challenge is to migrate your application from module based components to standalone components.
## Note
You can also test the [Angular schematic](https://angular.io/guide/standalone-migration) to migrate NgModule to Standalone components. _(Since we are using nx, start your command with nx instead of ng)_

View File

@@ -9,10 +9,6 @@ sidebar:
order: 105
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
:::note
This challenge is inspired by a real-life example that I simplified to create this nice challenge.
:::

View File

@@ -8,10 +8,6 @@ sidebar:
order: 106
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
> Big thanks to **Robin Goetz** and his [Spartan Project](https://github.com/goetzrobin/spartan).
> This challenge was proposed by Robin and is strongly inspired by his project.

View File

@@ -9,13 +9,9 @@ sidebar:
order: 201
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Angular offer the static function **ngTemplateContextGuard** to strongly type structural directive.
Angular offer the static function [`ngTemplateContextGuard`](https://angular.io/guide/structural-directives#typing-the-directives-context) to strongly type structural directive.
However the context of **NgTemplateOutlet** type is **Object**. But with the help of the above guard, we can improve that behavior.

View File

@@ -8,10 +8,6 @@ sidebar:
order: 2
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Communicating and having a global/local state in sync with your backend is the heart of any application. You will need to master these following best practises to build strong and reliable Angular Applications.
@@ -27,8 +23,7 @@ Currently we have a working example but filled with lots of bad practices.
What you will need to do:
- Avoid **any** as a type. Using Interface to leverage Typescript type system prevent errors
- Use a **separate service** for all your http calls and use a **BehaviourSubject** for your todoList
- Use **AsyncPipe** to subscribe to your todo list. _(Lets you handle subscription, unsubscription and refresh of the page when data has changed)_, avoid manual subscribe when it's not needed
- Use a **separate service** for all your http calls and use a **Signal** for your todoList
- Don't **mutate** data
```typescript
@@ -39,8 +34,6 @@ this.todos[todoUpdated.id - 1] = todoUpdated;
this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated];
```
- Use **ChangeDetection.OnPush**
### Step 2: Improve
- Add a **Delete** button: _<a href="https://jsonplaceholder.typicode.com/" target="_blank">Doc of fake API</a>_
@@ -53,5 +46,5 @@ this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]
### Step 4: Awesomeness!!! master your state.
- Use the **component store of ngrx** as a local state of your component. _(or any other 3rd Party lib)_
- Use the **component store of ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** or **ngrx/signal-store** as a local state of your component.
- Have a **localized** Loading/Error indicator, e.g. only on the Todo being processed and **disable** all buttons of the processed Todo. _(Hint: you will need to create an ItemComponent)_

View File

@@ -9,10 +9,6 @@ sidebar:
order: 102
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Structural directive is an important concept you will need to master to improve your angular skills and knowledge. This will be the first part of this challenge.
@@ -21,7 +17,7 @@ Guard is also very important since you will always need it in every application
## Statement
In LoginComponent, you will find 6 buttons corresponding at 6 differents users.
In LoginComponent, you will find 6 buttons corresponding to 6 differents user's role.
- Admin
- Manager
@@ -33,12 +29,12 @@ In LoginComponent, you will find 6 buttons corresponding at 6 differents users.
## Step 1
In **InformationComponent**, display the correct piece of information for each role.
In `InformationComponent`, you need to display the correct piece of information for each role using a structural directive.
### Constraints:
- no ngIf directive inside **InformationComponent**
- importing the store inside **InformationComponent** is not allowed.
- no `ngIf` of `@if` inside `InformationComponent`
- importing the store inside `InformationComponent` is not allowed.
You should end up with something like below:
@@ -56,4 +52,4 @@ You should end up with something like below:
## Step 2
In **Routes.ts**, route all user to the correct **DashboardComponent** using **CanMatch** guard.
In `Routes.ts`, you should route all users to the correct `DashboardComponent` using `CanMatch` guard.

View File

@@ -9,11 +9,7 @@ sidebar:
order: 3
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
The goal of this series of 3 pipe challenges is to master PIPES in Angular.
The goal of this series of 3 pipe challenges is to master **pipe** in Angular.
Pure pipes are a very useful way to transform data from your template. The difference between calling a function and a pipe is that pure pipes are memoized. So they won't be recalculated every change detection cycle if their inputs haven't changed.

View File

@@ -9,20 +9,14 @@ sidebar:
order: 103
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
<div class="chip">Challenge #9</div>
The goal of this series of 3 pipe challenges is to master PIPES in Angular.
The goal of this series of 3 pipe challenges is to master **pipe** in Angular.
Pure pipes are a very useful way to transform data from your template. The difference between calling a function and a pipe is that pure pipes are memoized. So they won't be recalculated every change detection cycle if their inputs haven't changed.
## Information:
In this second exercice, you are calling multiple functions inside your template. You can create a specific pipe for each of the functions but this will be too cumbersome.
The goal is to create a `wrapFn` pipe to wrap your callback function though a pipe. Your function MUST remain inside your component. `WrapFn` must be highly reusable.
The goal is to create a `wrapFn` pipe to wrap your callback function though a pipe. Your function MUST remain inside your component. **`WrapFn` must be highly reusable.**
## Constraints:

View File

@@ -9,10 +9,6 @@ sidebar:
order: 113
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
For this exercice, you will have a dashboard of activities displaying the name, the main teacher and a list of subtitutes.
## Information

View File

@@ -8,10 +8,6 @@ sidebar:
order: 206
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
NgRx Effect is a very powerful library developed by the NgRx team. Effects subscribe to a HOT Observable and listen to any event dispatched from any place inside the application.

View File

@@ -7,10 +7,6 @@ sidebar:
order: 207
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Welcome to the marvelous world of Nx generators.

View File

@@ -7,10 +7,6 @@ sidebar:
order: 116
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Welcome to the marvelous world of Nx generators.
@@ -41,7 +37,9 @@ Just below, you will have the end result of your generator for a `UserComponent`
standalone: true,
imports: [LetDirective],
providers: [provideComponentStore(UserStore)],
template: ` <ng-container *ngrxLet="vm$ as vm"> // do things </ng-container> `,
template: `
<ng-container *ngrxLet="vm$ as vm">// do things</ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UserComponent {

View File

@@ -7,10 +7,6 @@ sidebar:
order: 12
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Eslint is an amazing tool that helps developers avoid simple mistakes and adhere to company style guides.

View File

@@ -8,8 +8,6 @@ sidebar:
order: 8
---
<div class="chip">Challenge #35</div>
## Information
In Angular, <b>pure Pipes</b> are very powerful because the value is memoized, which means if the input value doesn't change, the `transform` function of the pipe is not recomputed, and the cached value is outputted.

View File

@@ -8,15 +8,11 @@ sidebar:
order: 114
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
Let's dive inside the wonderful word of RxJs.
This challenge is inspired by a real-life example.
## Presentation of the challenge
## Information
### User Story
@@ -26,7 +22,7 @@ We need a button for each `Topic`. When we click on it, we delete all objects wi
We can only pass one object to our DB for deletion at the time. The DB will respond true if the data was successfully deleted and false otherwise.
### What you need to do
### Statement
The QA team reports a **bug**. The UI shows **All [topic] have been deleted** all the time, even if some deletions fail.

View File

@@ -8,10 +8,6 @@ sidebar:
order: 11
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
The goal of this application is to display a list of topics in a modal when a button is clicked. The application functions correctly. However, your tech lead has asked you to add tests and they are failing.

View File

@@ -8,10 +8,6 @@ sidebar:
order: 9
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Statement:
The objective of this challenge is to have a better understanding of the CDK test harness API. In this initial challenge, we will only use Angular Material's built-in harnesses.

View File

@@ -8,10 +8,6 @@ sidebar:
order: 112
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
The goal of this challenge is to create a test harness for `slider.component.ts`. The harness file, `slider.harness.ts`, has already been created.

View File

@@ -9,10 +9,6 @@ sidebar:
order: 115
---
:::note
WIP: The following documentation will be reviewed and improved. However, you can still take on the challenge. If you don't understand a certain part, please feel free to reach out or create an issue.
:::
## Information
Angular uses TypeScript, and mastering TypeScript can help you avoid runtime errors by catching them at compile time.

View File

@@ -3,8 +3,6 @@ title: Welcome to Angular Challenges
description: Get started by resolving those challenges and becoming a better Angular FrontEnd engineer.
template: splash
noCommentSection: true
banner:
content: I will have less free time in the next two months, so don't worry if your pull requests take some time to be reviewed.
hero:
tagline: Start now and become an Angular Expert!
image: