mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 12:53:03 -05:00
fix: many grammar tweaks (#957)
* fix: many grammar tweaks Fix some typos. Follow some non-obvious English punctuation rules. remove duplicate md files for 50. Add some links for Angular Testing Library Remove inconsistent colons after "Constraints" headers Fix a broken link on 9. Chrome's tab is "Elements", not "source" Add missing challenges to the performance page Similar changes * fix: add LMFinney as contributor on tweaked files
This commit is contained in:
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 10
|
challengeNumber: 10
|
||||||
command: angular-utility-wrapper-pipe
|
command: angular-utility-wrapper-pipe
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -14,13 +15,13 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
This is the third of three `@Pipe()` challenges, the goal of this series is to master **pipes** in Angular.
|
This is the third of three `@Pipe()` challenges. The goal of this series is to master **pipes** in Angular.
|
||||||
|
|
||||||
Pipes are a very powerful way to transform data in 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.
|
Pipes are a very powerful way to transform data in 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.
|
||||||
|
|
||||||
Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improving rendering performance.
|
Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improve rendering performance.
|
||||||
|
|
||||||
By default a pipe is pure, you should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders.
|
By default, a pipe is pure. You should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
A **pure** pipe is only called when the value changes.\
|
A **pure** pipe is only called when the value changes.\
|
||||||
@@ -31,7 +32,7 @@ There are some useful predefined pipes like the DatePipe, UpperCasePipe and Curr
|
|||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
In this exercise, you want to access utils functions. Currently you cannot access them directly from your template. The goal is to create a specific pipe for this utils file, where you will need to pass the name of the function you want to call and the needed arguments.
|
In this exercise, you want to access utils functions. Currently, you cannot access them directly from your template. The goal is to create a specific pipe for this utils file, where you will need to pass the name of the function you want to call and the needed arguments.
|
||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- kabrunko-dev
|
- kabrunko-dev
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 13
|
challengeNumber: 13
|
||||||
command: angular-highly-customizable-css
|
command: angular-highly-customizable-css
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -14,7 +15,7 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## 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. 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.
|
In this challenge, you will need to use both CSS variables and `:host-context` to remove all `@Input()` from your code.
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: 🟢 @RouterInput()
|
title: 🟢 @RouterInput()
|
||||||
description: Challenge 22 is about using the @Input decorator to retreive router params.
|
description: Challenge 22 is about using the @Input decorator to retrieve router params.
|
||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 22
|
challengeNumber: 22
|
||||||
command: angular-router-input
|
command: angular-router-input
|
||||||
blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617
|
blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- kabrunko-dev
|
- kabrunko-dev
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 3
|
challengeNumber: 3
|
||||||
command: angular-directive-enhancement
|
command: angular-directive-enhancement
|
||||||
blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c
|
blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c
|
||||||
@@ -20,15 +21,15 @@ This exercise can feel obsolete with the new control flow and the empty block in
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
Directive is a very powerful tool only offered by the Angular framework. You can apply the DRY principle by having shared logic inside a directive and applying it to any component you want.
|
Directives are a very powerful tool only offered by the Angular framework. You can apply the DRY principle by having shared logic inside a directive and applying it to any component you want.
|
||||||
|
|
||||||
But the real power is that you can enhance an already existing directive which moreover doesn't **belong** to you.
|
But the real power is that you can enhance an already-existing directive, which moreover doesn't **belong** to you.
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
In this exercise, we have a want to display a list of persons. If the list is empty, you must display _" the list is empty !! "_.
|
In this exercise, we have a want to display a list of persons. If the list is empty, you must display _" the list is empty !! "_.
|
||||||
|
|
||||||
Currently we have:
|
Currently, we have:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
<ng-container *ngIf="persons.length > 0; else emptyList">
|
<ng-container *ngIf="persons.length > 0; else emptyList">
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 32
|
challengeNumber: 32
|
||||||
command: angular-change-detection-bug
|
command: angular-change-detection-bug
|
||||||
blogLink: https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629
|
blogLink: https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629
|
||||||
@@ -19,7 +20,7 @@ This challenge is inspired by a real-life example that I simplified to create th
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
In this small application, we have a navigation menu to route our application to either `BarComponent` or `FooComponent`. However our application is not loading and no errors are displayed inside the console.
|
In this small application, we have a navigation menu to route our application to either `BarComponent` or `FooComponent`. However, our application is not loading and no errors are displayed inside the console.
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ author: thomas-laforge
|
|||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 33
|
challengeNumber: 33
|
||||||
command: angular-decoupling-components
|
command: angular-decoupling-components
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -18,9 +19,9 @@ sidebar:
|
|||||||
|
|
||||||
The goal of this challenge is to separate the behavior of a component from its style. For the purpose of this challenge, we will be working on a button element. When we click on it, we will toggle a _disabled_ property which will change the style of the element. This is quite useless in real life but the challenge aims to demonstrate a useful concept.
|
The goal of this challenge is to separate the behavior of a component from its style. For the purpose of this challenge, we will be working on a button element. When we click on it, we will toggle a _disabled_ property which will change the style of the element. This is quite useless in real life but the challenge aims to demonstrate a useful concept.
|
||||||
|
|
||||||
The behavior of the component (referred to as the _brain_ in the Spartan stack) is located in the brain library. The styling part (referred to as the _helmet_) is located inside the helmet library. Both libraries cannot depend on each other because we want to be able to publish them separately. To help us address the issue, we are using the Nx enforce eslint rule. You can find more details [here](https://nx.dev/core-features/enforce-module-boundaries).
|
The behavior of the component (referred to as the _brain_ in the Spartan stack) is located in the brain library. The styling part (referred to as the _helmet_) is located inside the helmet library. Both libraries cannot depend on each other because we want to be able to publish them separately. To help us address the issue, we are using the Nx `enforce-module-boundaries` eslint rule. You can find more details [here](https://nx.dev/core-features/enforce-module-boundaries).
|
||||||
|
|
||||||
However the button's helmet needs to access the state of the component to style the button differently based on its state. As mention above, we cannot import the `BtnDisabledDirective` directly into the helmet library as done currently. If you go to [`BtnHelmetDirective`](../../libs/decoupling/helmet/src/lib/btn-style.directive.ts), you will encounter a linting error. **A project tagged with `type:hlm` can only depend on libs tagged with `type:core`**.
|
However, the button's helmet needs to access the state of the component to style the button differently based on its state. As mentioned above, we cannot import the `BtnDisabledDirective` directly into the helmet library as done currently. If you go to [`BtnHelmetDirective`](../../libs/decoupling/helmet/src/lib/btn-style.directive.ts), you will encounter a linting error. **A project tagged with `type:hlm` can only depend on libs tagged with `type:core`**.
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 🟠 InjectionToken
|
title: 🟠 InjectionToken
|
||||||
description: Challenge 39 is about learning the power of dependancy injection
|
description: Challenge 39 is about learning the power of dependency injection
|
||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 39
|
challengeNumber: 39
|
||||||
command: angular-injection-token
|
command: angular-injection-token
|
||||||
sidebar:
|
sidebar:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 4
|
challengeNumber: 4
|
||||||
command: angular-typed-context-outlet
|
command: angular-typed-context-outlet
|
||||||
blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6
|
blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6
|
||||||
@@ -18,7 +19,7 @@ sidebar:
|
|||||||
|
|
||||||
You can improve template type checking for custom directives by adding template guard properties to your directive definition. Angular offers the static function [`ngTemplateContextGuard`](https://angular.dev/guide/directives/structural-directives#improving-template-type-checking-for-custom-directives) to strongly type structural directives.
|
You can improve template type checking for custom directives by adding template guard properties to your directive definition. Angular offers the static function [`ngTemplateContextGuard`](https://angular.dev/guide/directives/structural-directives#improving-template-type-checking-for-custom-directives) to strongly type structural directives.
|
||||||
|
|
||||||
However the context of **NgTemplateOutlet** type is **Object**. But with the help of the above guard, we can improve that behavior.
|
However, the context of **NgTemplateOutlet** type is **Object**. But with the help of the above guard, we can improve that behavior.
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
@@ -28,17 +29,17 @@ This exercise has two levels of complexity.
|
|||||||
|
|
||||||
### Level 1: Known Interface
|
### Level 1: Known Interface
|
||||||
|
|
||||||
Currently we have the following piece of code.
|
Currently, we have the following piece of code.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
As we can see, `name` is of type `any`. We want to infer the correct type using the custom directive `PersonDirective`.
|
As we can see, `name` is of type `any`. We want to infer the correct type using the custom directive `PersonDirective`.
|
||||||
|
|
||||||
### Level 2: Generic Interface
|
### Level 2: Generic Interface
|
||||||
|
|
||||||
Currently we have the following piece of code.
|
Currently, we have the following piece of code.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
As we can see, `student` is of type `any`. We want to infer the correct type using the custom directive `ListDirective`.
|
As we can see, `student` is of type `any`. We want to infer the correct type using the custom directive `ListDirective`.
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ author: thomas-laforge
|
|||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 44
|
challengeNumber: 44
|
||||||
command: angular-view-transition
|
command: angular-view-transition
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -13,9 +14,9 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
This is the second of two animation challenges, the goal of this series is to master animations in Angular.
|
This is the second of two animation challenges. The goal of this series is to master animations in Angular.
|
||||||
|
|
||||||
The View Transition API is a brand new API that provides a set of features that allow developers to control and manipulate the transitions and animations between views within an application.
|
The View Transition API is a brand-new API that provides a set of features that allow developers to control and manipulate the transitions and animations between views within an application.
|
||||||
It plays a pivotal role in enhancing the user experience (UX), bringing applications to life with engaging and captivating transitions to guide users through different pages or sections of the app.
|
It plays a pivotal role in enhancing the user experience (UX), bringing applications to life with engaging and captivating transitions to guide users through different pages or sections of the app.
|
||||||
|
|
||||||
The goal of this challenge is to learn about and manipulate all types of transitions proposed by the API.
|
The goal of this challenge is to learn about and manipulate all types of transitions proposed by the API.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- wandri
|
- wandri
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 45
|
challengeNumber: 45
|
||||||
command: angular-react-in-angular
|
command: angular-react-in-angular
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -57,7 +58,7 @@ npm i --save-dev @types/react @types/react-dom
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Hint 2 - Initialization</summary>
|
<summary>Hint 2 - Initialization</summary>
|
||||||
Create a react root with `createRoot(...)`
|
Create a React root with `createRoot(...)`
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -76,5 +77,5 @@ npm i --save-dev @types/react @types/react-dom
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Hint 4 - Design</summary>
|
<summary>Hint 4 - Design</summary>
|
||||||
Do not forget to allow the react file in Tailwind.
|
Do not forget to allow the React file in Tailwind.
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 46 is about learning Angular's integrated animation API
|
|||||||
author: sven-brodny
|
author: sven-brodny
|
||||||
contributors:
|
contributors:
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 46
|
challengeNumber: 46
|
||||||
command: angular-simple-animations
|
command: angular-simple-animations
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -12,7 +13,7 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
This is the first of two animation challenges, the goal of this series is to master animations in Angular.
|
This is the first of two animation challenges. The goal of this series is to master animations in Angular.
|
||||||
|
|
||||||
Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic. Animations can improve your application and user experience in a number of ways:
|
Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic. Animations can improve your application and user experience in a number of ways:
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ Well-designed animations can make your application more fun and straightforward
|
|||||||
|
|
||||||
I would recommend you read the [official documentation](https://angular.dev/guide/animations). You will learn everything that is necessary to successfully complete the challenge.
|
I would recommend you read the [official documentation](https://angular.dev/guide/animations). You will learn everything that is necessary to successfully complete the challenge.
|
||||||
|
|
||||||
Otherwise look at this [working example](https://svenson95.github.io/ng-xmp-animations/) and [git repo](https://github.com/svenson95/ng-xmp-animations) to get inspired.
|
Otherwise, look at this [working example](https://svenson95.github.io/ng-xmp-animations/) and [git repo](https://github.com/svenson95/ng-xmp-animations) to get inspired.
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 5
|
challengeNumber: 5
|
||||||
command: angular-crud-application
|
command: angular-crud-application
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -21,7 +22,7 @@ Communicating and having a global/local state in sync with your backend is the h
|
|||||||
|
|
||||||
In this exercise, you have a small CRUD application, which get a list of TODOS, update and delete some todos.
|
In this exercise, you have a small CRUD application, which get a list of TODOS, update and delete some todos.
|
||||||
|
|
||||||
Currently we have a working example but filled with lots of bad practices.
|
Currently, we have a working example but filled with lots of bad practices.
|
||||||
|
|
||||||
### Step 1: refactor with best practices
|
### Step 1: refactor with best practices
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: 🟢 Bug in Effect ?
|
|
||||||
description: Challenge 50 is about understanding why an effect is not triggered.
|
|
||||||
author: thomas-laforge
|
|
||||||
contributors:
|
|
||||||
- tomalaforge
|
|
||||||
challengeNumber: 50
|
|
||||||
command: angular-bug-effect-signal
|
|
||||||
sidebar:
|
|
||||||
order: 19
|
|
||||||
---
|
|
||||||
|
|
||||||
## Information
|
|
||||||
|
|
||||||
In this basic exercise, we aim to display an alert whenever at least one checkbox is checked.
|
|
||||||
|
|
||||||
## Statement
|
|
||||||
|
|
||||||
The alert correctly triggers when clicking on each checkbox separately. However, if you first click on one checkbox and then click on a second one, the alert fails to appear. Why does this happen?
|
|
||||||
|
|
||||||
The objective of this challenge is to understand and correct the issue preventing the alert from appearing when the second checkbox is clicked.
|
|
||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- kabrunko-dev
|
- kabrunko-dev
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 8
|
challengeNumber: 8
|
||||||
command: angular-pure-pipe
|
command: angular-pure-pipe
|
||||||
blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d
|
blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d
|
||||||
@@ -16,13 +17,13 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
This is the first of three `@Pipe()` challenges, the goal of this series is to master **pipes** in Angular.
|
This is the first of three `@Pipe()` challenges. The goal of this series is to master **pipes** in Angular.
|
||||||
|
|
||||||
Pipes are a very powerful way to transform data in 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.
|
Pipes are a very powerful way to transform data in 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.
|
||||||
|
|
||||||
Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improving rendering performance.
|
Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improve rendering performance.
|
||||||
|
|
||||||
By default a pipe is pure, you should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders.
|
By default, a pipe is pure. You should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
A **pure** pipe is only called when the value changes.\
|
A **pure** pipe is only called when the value changes.\
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- kabrunko-dev
|
- kabrunko-dev
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 9
|
challengeNumber: 9
|
||||||
command: angular-wrap-function-pipe
|
command: angular-wrap-function-pipe
|
||||||
blogLink: https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d
|
blogLink: https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d
|
||||||
@@ -16,26 +17,26 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
This is the second of three `@Pipe()` challenges, the goal of this series is to master **pipes** in Angular.
|
This is the second of three `@Pipe()` challenges. The goal of this series is to master **pipes** in Angular.
|
||||||
|
|
||||||
Pipes are a very powerful way to transform data in 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.
|
Pipes are a very powerful way to transform data in 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.
|
||||||
|
|
||||||
Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improving rendering performance.
|
Pipes are designed to be efficient and optimized for performance. They use change detection mechanisms to only recalculate the value if the input changes, to minimize unnecessary calculations and improve rendering performance.
|
||||||
|
|
||||||
By default a pipe is pure, you should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders.
|
By default, a pipe is pure. You should be aware that setting `pure` to false is prone to be inefficient, because it increases the amount of rerenders.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
A **pure** pipe is only called when the value changes.\
|
A **pure** pipe is only called when the value changes.\
|
||||||
A **impure** pipe is called every change detection cycle.
|
A **impure** pipe is called every change detection cycle.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
There are some useful predefined pipes like the DatePipe, UpperCasePipe and CurrencyPipe. To learn more about pipes in Angular, check the API documentation [here]https://angular.dev/guide/pipes).
|
There are some useful predefined pipes like the DatePipe, UpperCasePipe and CurrencyPipe. To learn more about pipes in Angular, check the API documentation [here](https://angular.dev/guide/pipes).
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
In this exercise, 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.
|
In this exercise, 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 through 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 through a pipe. Your function MUST remain inside your component. **`WrapFn` must be highly reusable.**
|
||||||
|
|
||||||
## Constraints:
|
## Constraints
|
||||||
|
|
||||||
- Must be strongly typed
|
- Must be strongly typed
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ author: timothy-alcaide
|
|||||||
contributors:
|
contributors:
|
||||||
- alcaidio
|
- alcaidio
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 48
|
challengeNumber: 48
|
||||||
command: forms-avoid-losing-form-data
|
command: forms-avoid-losing-form-data
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -26,7 +27,6 @@ Here's the feature expressed as a user story with a functional expectation:
|
|||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
|
|
||||||
1. If one of the form fields is not empty and the user tries to navigate to a different route or page, or wants to reload the page, show an alert dialog to _avoid losing form data_.
|
1. If one of the form fields is not empty and the user tries to navigate to a different route or page, or wants to reload the page, show an alert dialog to _avoid losing form data_.
|
||||||
|
|
||||||
2. The content of `dialog.component.ts` must be used for your alert.
|
2. The content of `dialog.component.ts` must be used for your alert.
|
||||||
3. The appearance and behavior of the alert dialog box must comply with W3C conventions, see [alert dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/).
|
3. The appearance and behavior of the alert dialog box must comply with W3C conventions, see [alert dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/).
|
||||||
4. Maximize the use of the new concepts and syntax in the latest version of Angular.
|
4. Maximize the use of the new concepts and syntax in the latest version of Angular.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 2
|
challengeNumber: 2
|
||||||
command: ngrx-effect-vs-selector
|
command: ngrx-effect-vs-selector
|
||||||
blogLink: https://medium.com/@thomas.laforge/ngrx-effect-vs-reducer-vs-selector-58337ab59043
|
blogLink: https://medium.com/@thomas.laforge/ngrx-effect-vs-reducer-vs-selector-58337ab59043
|
||||||
@@ -14,22 +15,22 @@ sidebar:
|
|||||||
order: 113
|
order: 113
|
||||||
---
|
---
|
||||||
|
|
||||||
For this exercise, you will have a dashboard of activities displaying the name, the main teacher and a list of subtitutes.
|
For this exercise, you will have a dashboard of activities displaying the name, the main teacher and a list of possible substitutes.
|
||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
In NgRx, **selectors** is a very powerful tool often **misused**. You should use them as soon as you need to transform an already existing data in the store.
|
In NgRx, **selectors** is a very powerful tool that is often **misused**. You should use them as soon as you need to transform an already existing data in the store.
|
||||||
|
|
||||||
- You shouldn't store **derived state**. This is error prone because when your data changes, you will have to change it at multiple places => you should have only one place of truth with that data, and every transformation should be done in a **selector**.
|
- You shouldn't store **derived state**. This is error-prone because when your data changes, you will have to change it at multiple places => you should have only one place of truth with that data, and every transformation should be done in a **selector**.
|
||||||
|
|
||||||
- Inside a component, you shouldn't transform a selector (using map operator), or you shouldn't have to call a selector from a function in your view. The useful data for a component should be done in a **selector**.
|
- Inside a component, you shouldn't transform a selector (using the map operator), and you shouldn't have to call a selector from a function in your view. The useful logic for preparing data for a component should be done in a **selector**.
|
||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
You will have to Refactor this working example of a dashboard of activities.
|
You will have to refactor this working example of a dashboard of activities.
|
||||||
|
|
||||||
## Contraints:
|
## Constraints
|
||||||
|
|
||||||
- Only **one action** should be dispatched from a component
|
- Only **one action** should be dispatched from a component (or none, if you can solve the problem with Effect lifecycle hooks).
|
||||||
- Status effect is useless. Using **combineLatest** should be a red flag. And Effect are made for side effect, not transforming data. That's a selector role
|
- Status effect is useless. Using **combineLatest** should be a red flag. Effects are made for side effects, not for transforming data. That's a selector's role.
|
||||||
- Status state might not be useful, it's only a **derived state** of existing state.
|
- Status state might not be useful; it's only a **derived state** of existing state.
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: 🔴 Power of Effect
|
title: 🔴 Power of Effect
|
||||||
description: Challenge 7 is about creating an Ngrx effect with another Rxjs Hot observable
|
description: Challenge 7 is about creating an NgRx effect with another Rxjs Hot observable
|
||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 7
|
challengeNumber: 7
|
||||||
command: ngrx-power-of-effect
|
command: ngrx-power-of-effect
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -28,11 +29,11 @@ Create an injection token to `inject` the push service inside each component. In
|
|||||||
|
|
||||||
_Eliminate_ the notification service. It is not extensible. Testing (not required for this challenge) the notification service would also be overly complicated. You would need to test each branching scenario. Injection tokens can easily be mocked.
|
_Eliminate_ the notification service. It is not extensible. Testing (not required for this challenge) the notification service would also be overly complicated. You would need to test each branching scenario. Injection tokens can easily be mocked.
|
||||||
|
|
||||||
Since the notification service is global, all component lists update whether or not, a user is on that route. We need to decouple that logic. The notification messages should display only on their respective routes.
|
Since the notification service is global, all component lists update, even if a user is not on that route. We need to decouple that logic. The notification messages should display only on their respective routes.
|
||||||
|
|
||||||
### Step 2
|
### Step 2
|
||||||
|
|
||||||
Create one ngrx effect, or component store effect for each push type, and implement your logic.
|
Create one NgRx effect or component store effect for each push type, and implement your logic.
|
||||||
|
|
||||||
### Step 3
|
### Step 3
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 25 is about creating a Nx generator to extend the built-i
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 25
|
challengeNumber: 25
|
||||||
sidebar:
|
sidebar:
|
||||||
order: 207
|
order: 207
|
||||||
@@ -21,9 +22,9 @@ The goal of this challenge is to create a generator that extends the default lib
|
|||||||
|
|
||||||
You can either use all the default parameters of the Nx library generator or choose to modify some and keep others as defaults. The choice is yours.
|
You can either use all the default parameters of the Nx library generator or choose to modify some and keep others as defaults. The choice is yours.
|
||||||
|
|
||||||
## Constraints:
|
## Constraints
|
||||||
|
|
||||||
You should only override the jest configuration is the `unitTestRunner` option is set at `JEST`, and you should only update the eslint configuration if the `linter` is set to `eslint`.
|
You should only override the jest configuration is the `unitTestRunner` option is set at `jest`, and you should only update the eslint configuration if the `linter` is set to `eslint`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -52,4 +53,4 @@ export default {
|
|||||||
|
|
||||||
`eslintrc.json`
|
`eslintrc.json`
|
||||||
|
|
||||||
add this rule `"@typescript-eslint/member-ordering": "off"` inside the rules properties of ts files.
|
Add the rule `"@typescript-eslint/member-ordering": "off"` inside the rules properties of ts files.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- Sagardevkota
|
- Sagardevkota
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 26
|
challengeNumber: 26
|
||||||
sidebar:
|
sidebar:
|
||||||
order: 116
|
order: 116
|
||||||
@@ -21,7 +22,7 @@ Generators are awesome tools that can help you and your team generate code more
|
|||||||
|
|
||||||
The goal of this challenge is to create a generator that will create all the boilerplate of a component for you.
|
The goal of this challenge is to create a generator that will create all the boilerplate of a component for you.
|
||||||
|
|
||||||
Just below, you will have the end result of your generator for a `UserComponent` associated with a `@ngrx/component-store`.
|
Below are the end result of your generator for a `UserComponent` associated with a `@ngrx/component-store`.
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 12 about optimizing the number of change detection cycle
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 12
|
challengeNumber: 12
|
||||||
command: performance-optimize-change-detection
|
command: performance-optimize-change-detection
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -37,4 +38,4 @@ Your goal for this challenge is to avoid all unnecessary change detection cycles
|
|||||||
|
|
||||||
## Constraint:
|
## Constraint:
|
||||||
|
|
||||||
You cannot opt-out of Zone.js globally. If this code is part of a large project and you opt out of Zone.js, you will break your application without any doubt.
|
You cannot opt out of Zone.js globally. If this code is part of a large project, and you opt out of Zone.js, you will break your application without any doubt.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 35 is about learning how pure pipe works
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 35
|
challengeNumber: 35
|
||||||
command: performance-memoization
|
command: performance-memoization
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -45,6 +46,6 @@ The goal of this challenge is to understand what is causing this latency and to
|
|||||||
<details>
|
<details>
|
||||||
<summary>Hint 1</summary>
|
<summary>Hint 1</summary>
|
||||||
|
|
||||||
Use `Pipes` to memoize the Fibonnaci computation.
|
Use `Pipes` to memoize the Fibonacci computation.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 36 is about learning how trackby works
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 36
|
challengeNumber: 36
|
||||||
command: performance-ngfor-optimization
|
command: performance-ngfor-optimization
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -12,7 +13,7 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
In this application, we have a list of individuals that we can add, delete or update. If you open the developer Chrome panel by pressing **F12**, go to he <b>source</b> tab, and expand the element to see the list, you will notice that each time, you add, delete or update a list item, the entire DOM elements are destroyed and initialized again. (See video below).
|
In this application, we have a list of individuals that we can add, delete or update. If you open the developer Chrome panel by pressing **F12**, go to the <b>Elements</b> tab, and expand the element to see the list, you will notice that each time you add, delete or update a list item, all the DOM elements are destroyed and initialized again. (See video below).
|
||||||
|
|
||||||
<video controls src="https://github.com/tomalaforge/angular-challenges/assets/30832608/71b90307-3ee3-42c0-a532-b67ce4f20bf6">
|
<video controls src="https://github.com/tomalaforge/angular-challenges/assets/30832608/71b90307-3ee3-42c0-a532-b67ce4f20bf6">
|
||||||
</video>
|
</video>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ author: thomas-laforge
|
|||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 37
|
challengeNumber: 37
|
||||||
command: performance-optimize-big-list
|
command: performance-optimize-big-list
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -13,7 +14,7 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
In this application, we will render a list of 100,000 individuals by clicking on the **loadList** button. If you open the Chrome developer panel by pressing **F12**, go to the <b>Source</b> tab, and expand the element to see the list, you will notice that all 100,000 elements are rendered in the DOM, even though we can only see about 20 elements in the viewport. This process takes a lot of time, which is why the application is very slow at displaying the list.
|
In this application, we will render a list of 100,000 individuals by clicking on the **loadList** button. If you open the Chrome developer panel by pressing **F12**, go to the <b>Elements</b> tab, and expand the element to see the list, you will notice that all 100,000 elements are rendered in the DOM, even though we can only see about 20 elements in the viewport. This process takes a lot of time, which is why the application is very slow at displaying the list.
|
||||||
|
|
||||||
We can use the <b>Angular DevTool</b> to profile our application and understand what is happening inside our application. I will show you how to do it inside the following video.
|
We can use the <b>Angular DevTool</b> to profile our application and understand what is happening inside our application. I will show you how to do it inside the following video.
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ next: false
|
|||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
|
- LMFinney
|
||||||
description: Learn how to use the Angular Devtool chrome extension.
|
description: Learn how to use the Angular Devtool chrome extension.
|
||||||
noCommentSection: true
|
noCommentSection: true
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -15,7 +16,7 @@ import { LinkCard } from '@astrojs/starlight/components';
|
|||||||
|
|
||||||
In this series of challenges about performance, you will learn how to optimize and enhance the performance of your Angular application.
|
In this series of challenges about performance, you will learn how to optimize and enhance the performance of your Angular application.
|
||||||
|
|
||||||
Before starting to resolve any challenge, I invite you to download the [Angular DevTools Chrome extention](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) if you haven't already done so.
|
Before starting to resolve any challenge, I invite you to download the [Angular DevTools Chrome extension](https://chrome.google.com/webstore/detail/angular-devtools/ienfalfjdbdpebioblfackkekamfmbnh) if you haven't already done so.
|
||||||
|
|
||||||
This extension allows you to profile your application and detect performance issues, which is very useful for understanding where performance issues can occur.
|
This extension allows you to profile your application and detect performance issues, which is very useful for understanding where performance issues can occur.
|
||||||
|
|
||||||
@@ -45,8 +46,26 @@ Now that you know how to use the <b>Angular DevTool</b>, you can choose a challe
|
|||||||
href="/challenges/performance/35-memoization/"
|
href="/challenges/performance/35-memoization/"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟢 NgFor Optimization"
|
||||||
|
description="Learn how to improve looping performance."
|
||||||
|
href="/challenges/performance/36-ngfor-optimization/"
|
||||||
|
/>
|
||||||
|
|
||||||
<LinkCard
|
<LinkCard
|
||||||
title="🟠 Optimize Change Detection"
|
title="🟠 Optimize Change Detection"
|
||||||
description="Learn how to remove zone pollution."
|
description="Learn how to remove zone pollution."
|
||||||
href="/challenges/performance/12-optimize-change-detection/"
|
href="/challenges/performance/12-optimize-change-detection/"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Optimize Big List"
|
||||||
|
description="Learn how to handle large lists."
|
||||||
|
href="/challenges/performance/37-optimize-big-list/"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinkCard
|
||||||
|
title="🟠 Web workers"
|
||||||
|
description="Learn how to offload slow calculations."
|
||||||
|
href="/challenges/performance/40-web-worker/"
|
||||||
|
/>
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ description: Challenge 11 is about resolving a Rxjs bug because of high order op
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 11
|
challengeNumber: 11
|
||||||
command: rxjs-high-order-operator-bug
|
command: rxjs-high-order-operator-bug
|
||||||
sidebar:
|
sidebar:
|
||||||
order: 114
|
order: 114
|
||||||
---
|
---
|
||||||
|
|
||||||
Let's dive inside the wonderful word of RxJs.
|
Let's dive inside the wonderful word of RxJS.
|
||||||
|
|
||||||
This challenge is inspired by a real-life example.
|
This challenge is inspired by a real-life example.
|
||||||
|
|
||||||
@@ -18,9 +19,9 @@ This challenge is inspired by a real-life example.
|
|||||||
|
|
||||||
### User Story
|
### User Story
|
||||||
|
|
||||||
We need a button for each `Topic`. When we click on it, we delete all objects with this `Topic` in our database _(Fake DB in our case)_. Finally we display **All [topic] have been deleted** is everything was deleted successfully or **Error: deletion of some [topic] failed** if some deletions failed
|
We need a button for each `Topic`. When we click on it, we delete all objects with this `Topic` in our database _(Fake DB in our case)_. Finally, we display **All [topic] have been deleted** if everything was deleted successfully or **Error: deletion of some [topic] failed** if some deletions failed
|
||||||
|
|
||||||
### Constraints:
|
### Constraints
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 14 is about race condition in Rxjs
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 14
|
challengeNumber: 14
|
||||||
command: rxjs-race-condition
|
command: rxjs-race-condition
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -18,9 +19,9 @@ The goal of this application is to display a list of topics in a modal when a bu
|
|||||||
|
|
||||||
Correct your application to pass the test
|
Correct your application to pass the test
|
||||||
|
|
||||||
## Constraints:
|
## Constraints
|
||||||
|
|
||||||
- I can see you coming 🤣 => You CANNOT change the test (Test is working fine) 😳
|
- I can see you coming 🤣 => You CANNOT change the test (the test is working fine) 😳
|
||||||
- You CANNOT change the `fakeGetHttpTopic` method. A delay has been added to fake a slow network.
|
- You CANNOT change the `fakeGetHttpTopic` method. A delay has been added to fake a slow network.
|
||||||
|
|
||||||
## Run the test
|
## Run the test
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: 🟢 catchError
|
title: 🟢 catchError
|
||||||
description: Challenge 38 is about learning obervable completion.
|
description: Challenge 38 is about learning observable completion.
|
||||||
author: devesh-chaudhari
|
author: devesh-chaudhari
|
||||||
command: rxjs-catch-error
|
command: rxjs-catch-error
|
||||||
contributors:
|
contributors:
|
||||||
- DeveshChau
|
- DeveshChau
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 38
|
challengeNumber: 38
|
||||||
sidebar:
|
sidebar:
|
||||||
order: 14
|
order: 14
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: You're tasked with implementing Lucie's button design, requiring ho
|
|||||||
author: timothy-alcaide
|
author: timothy-alcaide
|
||||||
contributors:
|
contributors:
|
||||||
- alcaidio
|
- alcaidio
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 49
|
challengeNumber: 49
|
||||||
command: rxjs-hold-to-save-button
|
command: rxjs-hold-to-save-button
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -22,7 +23,7 @@ So you're going to take over from him.
|
|||||||
|
|
||||||
> "As a user, I would like to save something by holding down the button for a certain amount of time."
|
> "As a user, I would like to save something by holding down the button for a certain amount of time."
|
||||||
|
|
||||||
Here the prototype made by Lucie:
|
Here is the prototype made by Lucie:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ author: thomas-laforge
|
|||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 50
|
challengeNumber: 50
|
||||||
command: signal-bug-in-effect
|
command: signal-bug-in-effect
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -19,9 +20,9 @@ In this basic exercise, we aim to display an alert whenever at least one checkbo
|
|||||||
|
|
||||||
## Statement
|
## Statement
|
||||||
|
|
||||||
The actual implementation doesn't work as expected, your task is to fix the issue. Your team exposed a bug, there is a alert to be shown if atleast one of the three checkboxes is checked. But if the first one is checked, the other two checkboxes gets checked without displaying the alert. Why does this happen?
|
The actual implementation doesn't work as expected, and your task is to fix a bug that your team discovered. An alert should be shown if at least one of the three checkboxes is checked (independent of any other checkboxes). But if the first one is checked, checking one or both of the other two checkboxes does not cause the alert to display. Why does this happen?
|
||||||
|
|
||||||
The objective of this challenge is to understand the issue and fix the problem, preventing the alert from appearing when the second checkbox is clicked.
|
The objective of this challenge is to understand the issue and fix the problem that prevents the alert from appearing when the second checkbox is clicked.
|
||||||
|
|
||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 17 is about testing the router
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 17
|
challengeNumber: 17
|
||||||
command: testing-router
|
command: testing-router
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -14,13 +15,13 @@ sidebar:
|
|||||||
|
|
||||||
We have a functional application that lists available books for borrowing inside a library. If the book you searched for is available, you will be directed to the corresponding book(s), otherwise, you will end up on an error page.
|
We have a functional application that lists available books for borrowing inside a library. If the book you searched for is available, you will be directed to the corresponding book(s), otherwise, you will end up on an error page.
|
||||||
|
|
||||||
The file named `app.component.spec.ts` will let you test your application using Testing Library. To run the test suits, you need to run `npx nx test testing-router-outlet`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
The file named `app.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-router-outlet`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
||||||
|
|
||||||
For testing cypress, you will execute your test inside the `app.component.cy.ts` and run `npx nx component-test testing-router-outlet` to execute your test suits. You can add the `--watch` flag to execute your test in watch mode.
|
For testing with Cypress, you will execute your test inside the `app.component.cy.ts` and run `npx nx component-test testing-router-outlet` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode.
|
||||||
|
|
||||||
# Statement
|
# Statement
|
||||||
|
|
||||||
The goal is to test multiple behaviors of the application described in each test file using Testing library and Cypress Component Testing.
|
The goal is to test multiple behaviors of the application described in each test file using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview).
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
I have created some `it` blocks but feel free to add more tests if you want.
|
I have created some `it` blocks but feel free to add more tests if you want.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 18 is about testing nested components
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 18
|
challengeNumber: 18
|
||||||
command: testing-nested-components
|
command: testing-nested-components
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -12,19 +13,19 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
We have a small application that sends a title, typed into an input to a fake backend.
|
We have a small application that sends a title to a fake backend when the user types the value into an input.
|
||||||
If the title is correctly typed, you can send the request otherwise you receive an error and the request is not sent.
|
If the title is correctly typed, you can send the request; otherwise you receive an error, and the request is not sent.
|
||||||
The application is created with <b>nested components</b>. `ChildComponent` is the container that includes four components: `ResultComponent`, `ButtonComponent`, `InputComponent` and `ErrorComponent`. However since we are testing our component as a black box, the architecture of our components doesn't change anything. You can create your test, change how the components are structured, and your tests should still pass. That's the goal of integration tests. <b>Never test internal implementation details!!!</b>.
|
The application is created with <b>nested components</b>. `ChildComponent` is the container that includes four components: `ResultComponent`, `ButtonComponent`, `InputComponent` and `ErrorComponent`. However, since we are testing our component as a black box, the architecture of our components doesn't change anything. You can create your test, change how the components are structured, and your tests should still pass. That's the goal of integration tests. <b>Never test internal implementation details!!!</b>.
|
||||||
|
|
||||||
You can play with it by running : `npx nx serve testing-nested`.
|
You can play with it by running : `npx nx serve testing-nested`.
|
||||||
|
|
||||||
The file named `child.component.spec.ts` will let test your application using Testing Library. To run the test suits, you need to run `npx nx test testing-nested`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
The file named `child.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-nested`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
||||||
|
|
||||||
For testing cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-nested` to execute your test suits. You can add the `--watch` flag to execute your test in watch mode.
|
For testing with Cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-nested` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode.
|
||||||
|
|
||||||
# Statement
|
# Statement
|
||||||
|
|
||||||
The goal is to test multiple behaviors of the application describe inside each test files using Testing library and Cypress Component Testing.
|
The goal is to test multiple behaviors of the application describe inside each test files using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview).
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
I have created some `it` blocks but feel free to add more tests if you want.
|
I have created some `it` blocks but feel free to add more tests if you want.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 19
|
challengeNumber: 19
|
||||||
command: testing-input-output
|
command: testing-input-output
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -19,13 +20,13 @@ We have a small counter application that increments or decrements a number. The
|
|||||||
|
|
||||||
You can play with it by running : `npx nx serve testing-input-output`.
|
You can play with it by running : `npx nx serve testing-input-output`.
|
||||||
|
|
||||||
The file named `counter.component.spec.ts` will let test your application using Testing Library. To run the test suits, you need to run `npx nx test testing-input-output`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
The file named `counter.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-input-output`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
||||||
|
|
||||||
For testing cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-input-output` to execute your test suits. You can add the `--watch` flag to execute your test in watch mode.
|
For testing with Cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-input-output` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode.
|
||||||
|
|
||||||
# Statement
|
# Statement
|
||||||
|
|
||||||
The goal is to test multiple behaviors of the application described inside each test file using Testing library and Cypress Component Testing.
|
The goal is to test multiple behaviors of the application described inside each test file using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview).
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
I have created some `it` blocks but feel free to add more tests if you want.
|
I have created some `it` blocks but feel free to add more tests if you want.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 20
|
challengeNumber: 20
|
||||||
command: testing-modal
|
command: testing-modal
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -23,13 +24,13 @@ The goal of this challenge is to test the dialogs inside your application. To do
|
|||||||
|
|
||||||
You can play with it by running : `npx nx serve testing-modal`.
|
You can play with it by running : `npx nx serve testing-modal`.
|
||||||
|
|
||||||
The file named `app.component.spec.ts` will let you test your application using Testing Library. To run the test suites, you need to run `npx nx test testing-modal`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
The file named `app.component.spec.ts` will let you test your application using [Angular Testing Library](https://testing-library.com/) . To run the test suites, you need to run `npx nx test testing-modal`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
||||||
|
|
||||||
For testing with Cypress, you will execute your test inside `app.component.cy.ts` and run `npx nx component-test testing-modal` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode.
|
For testing with Cypress, you will execute your test inside `app.component.cy.ts` and run `npx nx component-test testing-modal` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode.
|
||||||
|
|
||||||
# Statement
|
# Statement
|
||||||
|
|
||||||
The goal is to test multiple behaviors of the application described inside each test file using Testing library and Cypress Component Testing.
|
The goal is to test multiple behaviors of the application described inside each test file using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview).
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
I have created some `it` blocks but feel free to add more tests if you want.
|
I have created some `it` blocks but feel free to add more tests if you want.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 23
|
challengeNumber: 23
|
||||||
command: testing-harness
|
command: testing-harness
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -26,4 +27,4 @@ Documentation for Angular Material component is [here](https://material.angular.
|
|||||||
|
|
||||||
Test the functionality of `child.component.ts`, which consists of some inputs & checkboxes related to a `mat-slider`. Implement the prepared test suite, but feel free to include additional tests as well.
|
Test the functionality of `child.component.ts`, which consists of some inputs & checkboxes related to a `mat-slider`. Implement the prepared test suite, but feel free to include additional tests as well.
|
||||||
|
|
||||||
**Note:** You are welcome to use Testing Library if you wish.
|
**Note:** You are welcome to use [Angular Testing Library](https://testing-library.com/) if you wish.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 28
|
challengeNumber: 28
|
||||||
command: testing-checkbox
|
command: testing-checkbox
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -14,9 +15,9 @@ sidebar:
|
|||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
This application is very simple. It consists of a checkbox that enables or disables a button. The primary goal of this application is to become familiar with the debug API of Testing Library. Knowing how to debug your tests is a crucial tool you need to have in your toolkit.
|
This application is very simple. It consists of a checkbox that enables or disables a button. The primary goal of this application is to become familiar with the debug API of [Angular Testing Library](https://testing-library.com/). Knowing how to debug your tests is a crucial tool you need to have in your toolkit.
|
||||||
|
|
||||||
You can find the documentation about debugging in Testing Library [here](https://testing-library.com/docs/dom-testing-library/api-debugging#screenlogtestingplaygroundurl).
|
You can find the documentation about debugging in Angular Testing Library [here](https://testing-library.com/docs/dom-testing-library/api-debugging#screenlogtestingplaygroundurl).
|
||||||
|
|
||||||
The main functions to remember are as follows:
|
The main functions to remember are as follows:
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ contributors:
|
|||||||
- tomalaforge
|
- tomalaforge
|
||||||
- tomer953
|
- tomer953
|
||||||
- svenson95
|
- svenson95
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 29
|
challengeNumber: 29
|
||||||
command: testing-real-life-application
|
command: testing-real-life-application
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -18,19 +19,19 @@ This application presents a greater challenge because it closely resembles a rea
|
|||||||
|
|
||||||
The application is a typical todo list application. You can filter tickets, create new ones, assign each ticket, close others, and navigate to the details of each ticket.
|
The application is a typical todo list application. You can filter tickets, create new ones, assign each ticket, close others, and navigate to the details of each ticket.
|
||||||
|
|
||||||
In this challenge, you will write tests for the `ListComponent`, which represents the global view, and the `RowComponent`, which represents a specific ticket. Additionally, you will need to write unit tests for the `TicketStoreService` using Testing Library. _This library allows you to test services effectively._
|
In this challenge, you will write tests for the `ListComponent`, which represents the global view, and the `RowComponent`, which represents a specific ticket. Additionally, you will need to write unit tests for the `TicketStoreService` using [Angular Testing Library](https://testing-library.com/) . _This library allows you to test services effectively._
|
||||||
|
|
||||||
Handling asynchronous tasks will be particularly challenging. It's important not to introduce any explicit <b>waits</b> in your tests, as this would introduce unnecessary delays. Instead, it's better to look for an element that needs to appear or disappear from the DOM. In this case, the test will naturally wait for the correct period of time, as the waits are already implemented within both libraries. Take advantage of these built-in functionalities to create efficient and reliable tests.
|
Handling asynchronous tasks will be particularly challenging. It's important not to introduce any explicit <b>waits</b> in your tests, as this would introduce unnecessary delays. Instead, it's better to look for an element that needs to appear or disappear from the DOM. In this case, the test will naturally wait for the correct period of time, as the waits are already implemented within both libraries. Take advantage of these built-in functionalities to create efficient and reliable tests.
|
||||||
|
|
||||||
You can play with it by running : `npx nx serve testing-todos-list`.
|
You can play with it by running : `npx nx serve testing-todos-list`.
|
||||||
|
|
||||||
To run Testing Library test suits, you need to run `npx nx test testing-todos-list`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
To run [Angular Testing Library](https://testing-library.com/) test suites, you need to run `npx nx test testing-todos-list`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks.
|
||||||
|
|
||||||
For testing cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-todos-list` to execute your test suits. You can add the `--watch` flag to execute your test in watch mode.
|
For testing with Cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-todos-list` to execute your test suites. You can add the `--watch` flag to execute your test in watch mode.
|
||||||
|
|
||||||
# Statement
|
# Statement
|
||||||
|
|
||||||
The goal is to test multiple behaviors of the application describe inside each test files using Testing library and Cypress Component Testing.
|
The goal is to test multiple behaviors of the application describe inside each test files using [Angular Testing Library](https://testing-library.com/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview).
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
I have created some `it` blocks but feel free to add more tests if you want.
|
I have created some `it` blocks but feel free to add more tests if you want.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ prev: false
|
|||||||
next: false
|
next: false
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
description: Introduction to testing challenges.
|
description: Introduction to testing challenges.
|
||||||
noCommentSection: true
|
noCommentSection: true
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -16,9 +17,9 @@ Testing is a crucial step in building scalable, maintainable, and trustworthy ap
|
|||||||
Testing should never be avoided, even in the face of short deadlines or strong pressure from the product team.
|
Testing should never be avoided, even in the face of short deadlines or strong pressure from the product team.
|
||||||
Nowadays, there are numerous awesome tools available that make it easy to test your code and provide a great developer experience.
|
Nowadays, there are numerous awesome tools available that make it easy to test your code and provide a great developer experience.
|
||||||
|
|
||||||
In this series of testing exercises, we will learn and master [Testing Library](https://testing-library.com/docs/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/angular/overview) that simplifies DOM manipulation for testing any Angular component.
|
In this series of testing exercises, we will learn and master [Angular Testing Library](https://testing-library.com/docs/) and [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/angular/overview) that simplifies DOM manipulation for testing any Angular component.
|
||||||
|
|
||||||
The benefits of using <b>Testing Library</b> or <b>Cypress Component Testing</b> are to test your component as a black box. You will only interact with what the user can do on the UI. However, the difference with end-to-end tests is that the backend is mocked, which makes the tests faster and more maintainable.
|
The benefits of using <b>Angular Testing Library</b> or <b>Cypress Component Testing</b> are to test your component as a black box. You will only interact with what the user can do on the UI. However, the difference with end-to-end tests is that the backend is mocked, which makes the tests faster and more maintainable.
|
||||||
The goal is to mock as little as possible to test your component at a higher level than unit testing, which will make refactoring easier.
|
The goal is to mock as little as possible to test your component at a higher level than unit testing, which will make refactoring easier.
|
||||||
Within a real application, integration tests are the tests you will write the most. Learning how to write them will make your application more robust and more maintainable.
|
Within a real application, integration tests are the tests you will write the most. Learning how to write them will make your application more robust and more maintainable.
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ Here is a series of 8 challenges that you can take in any order.
|
|||||||
|
|
||||||
<LinkCard
|
<LinkCard
|
||||||
title="🟢 Checkbox"
|
title="🟢 Checkbox"
|
||||||
description="Learn how to debug your tests using Testing Library on a simple checkbox application"
|
description="Learn how to debug your tests using [Angular Testing Library](https://testing-library.com/) on a simple checkbox application"
|
||||||
href="/challenges/testing/28-checkbox/"
|
href="/challenges/testing/28-checkbox/"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ description: Challenge 15 is about creating overload functions
|
|||||||
author: thomas-laforge
|
author: thomas-laforge
|
||||||
contributors:
|
contributors:
|
||||||
- tomalaforge
|
- tomalaforge
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 15
|
challengeNumber: 15
|
||||||
command: typescript-function-overload
|
command: typescript-function-overload
|
||||||
blogLink: https://medium.com/ngconf/function-overloading-in-typescript-8236706b2c05
|
blogLink: https://medium.com/ngconf/function-overloading-in-typescript-8236706b2c05
|
||||||
@@ -16,7 +17,7 @@ sidebar:
|
|||||||
Angular uses TypeScript, and mastering TypeScript can help you avoid runtime errors by catching them at compile time.
|
Angular uses TypeScript, and mastering TypeScript can help you avoid runtime errors by catching them at compile time.
|
||||||
|
|
||||||
In this challenge, we have a function to create a vehicle. However, each vehicle type requires different mandatory properties.
|
In this challenge, we have a function to create a vehicle. However, each vehicle type requires different mandatory properties.
|
||||||
Currently, we are getting an error at runtime if one property is missing and we don't get the return Type, which is not ideal.
|
Currently, we are getting an error at runtime if one property is missing, and we don't get the return Type, which is not ideal.
|
||||||
One solution would be to create a separate function for each vehicle type, but for this challenge, I want to use the same function and have TypeScript automatically complete the properties depending on the type passed as the first parameter.
|
One solution would be to create a separate function for each vehicle type, but for this challenge, I want to use the same function and have TypeScript automatically complete the properties depending on the type passed as the first parameter.
|
||||||
|
|
||||||
To achieve this, we will use overload functions.
|
To achieve this, we will use overload functions.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ author: sven-brodny
|
|||||||
contributors:
|
contributors:
|
||||||
- svenson95
|
- svenson95
|
||||||
- jdegand
|
- jdegand
|
||||||
|
- LMFinney
|
||||||
challengeNumber: 47
|
challengeNumber: 47
|
||||||
command: typescript-enums-vs-union-types
|
command: typescript-enums-vs-union-types
|
||||||
sidebar:
|
sidebar:
|
||||||
@@ -35,7 +36,7 @@ Enums are a concept borrowed from languages like C# and Java. TypeScript enums a
|
|||||||
Enums have some more pitfalls as well:
|
Enums have some more pitfalls as well:
|
||||||
|
|
||||||
- Non-const enums do not fit the concept of "a typed superset of JavaScript." They violate the concept by emitting global JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript (JavaScript uses dynamic typing rather than static typing; enums are a form of static typing). Since JavaScript has no compilation step, there is little or no value in having static typing.
|
- Non-const enums do not fit the concept of "a typed superset of JavaScript." They violate the concept by emitting global JavaScript objects that live in runtime with a syntax that is not compatible with JavaScript (JavaScript uses dynamic typing rather than static typing; enums are a form of static typing). Since JavaScript has no compilation step, there is little or no value in having static typing.
|
||||||
- Const enums, in contrast, cannot be transpiled with Babel. But there are workarounds for this issue, e. g., using the `babel-plugin-const-enum` plugin. The TypeScript documentation about [const enums](https://www.typescriptlang.org/docs/handbook/enums.html#const-enums) says "_Do not use const enums at all_".
|
- Const enums, in contrast, cannot be transpiled with Babel. But there are workarounds for this issue, e.g., using the `babel-plugin-const-enum` plugin. The TypeScript documentation about [const enums](https://www.typescriptlang.org/docs/handbook/enums.html#const-enums) says "_Do not use const enums at all_".
|
||||||
- To use enums, you have to import them. If you want to use enum values in a template, you'll need to declare a variable in your component too.
|
- To use enums, you have to import them. If you want to use enum values in a template, you'll need to declare a variable in your component too.
|
||||||
- Numeric enums are not type safe ...
|
- Numeric enums are not type safe ...
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user