mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-11 05:13:02 -05:00
feat(doc): improve documentation authoring exp
This commit is contained in:
59
docs/src/components/ChallengeFooter.astro
Normal file
59
docs/src/components/ChallengeFooter.astro
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
import VideoButton from './VideoButton.astro'
|
||||
|
||||
const {author, challengeNumber, title, blogLink, videoLink, command} = Astro.props.entry.data;
|
||||
|
||||
const authorLink = `https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A${challengeNumber}+label%3A"answer+author"`;
|
||||
const authorDescription = `${title} solution author`;
|
||||
const communityLink = `https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A${challengeNumber}+label%3Aanswer`;
|
||||
const communityDescription = `${title} community solutions`;
|
||||
|
||||
---
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
{command &&
|
||||
<aside aria-label="Note" class="starlight-aside starlight-aside--note"><p class="starlight-aside__title" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" class="starlight-aside__icon"><path d="M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z"></path></svg>Note</p><section class="starlight-aside__content">
|
||||
<p>Start the project by running: <code class="code" dir="auto">npx nx serve {command}</code>.</p></section></aside>
|
||||
}
|
||||
|
||||
<aside aria-label="Reminder" class="starlight-aside starlight-aside--tip"><p class="starlight-aside__title" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" class="starlight-aside__icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z"></path><path d="M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z"></path></svg>Reminder</p><section class="starlight-aside__content">
|
||||
<p>Your PR title must start with <b>Answer:{challengeNumber}</b>.</p></section></aside>
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href={communityLink}
|
||||
alt={communityDescription}>
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href={authorLink}
|
||||
alt={authorDescription}>
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
{blogLink && <a
|
||||
href={blogLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt={`${title} blog article`}>
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>}
|
||||
{videoLink && <VideoButton {...videoLink} />}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.separator {
|
||||
border-top: solid 1px var(--sl-color-hairline);
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.code {
|
||||
background-color: var(--sl-color-bg-inline-code);
|
||||
margin-block: -0.125rem;
|
||||
padding: 0.125rem 0.375rem;
|
||||
font-size: var(--sl-text-code-sm);
|
||||
}
|
||||
|
||||
</style>
|
||||
29
docs/src/components/CommentSection.astro
Normal file
29
docs/src/components/CommentSection.astro
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<script src="https://giscus.app/client.js"
|
||||
data-repo="tomalaforge/angular-challenges"
|
||||
data-repo-id="R_kgDOIXXIfw"
|
||||
data-category="Announcements"
|
||||
data-category-id="DIC_kwDOIXXIf84CSZF_"
|
||||
data-mapping="title"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="bottom"
|
||||
data-theme="preferred_color_scheme"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.separator {
|
||||
border-top: solid 1px var(--sl-color-hairline);
|
||||
margin: 3rem 0px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,41 +1,26 @@
|
||||
---
|
||||
import ChallengeFooter from './ChallengeFooter.astro'
|
||||
import CommentSection from './CommentSection.astro'
|
||||
import type { Props } from '@astrojs/starlight/props';
|
||||
import Default from '@astrojs/starlight/components/MarkdownContent.astro';
|
||||
|
||||
const slug = Astro.props.slug;
|
||||
const {challengeNumber, author} = Astro.props.entry.data;
|
||||
const renderCommentSection = !Astro.props.entry.data.noCommentSection;
|
||||
|
||||
---
|
||||
|
||||
{ challengeNumber && author && <p class="author">Created by {author}</p> }
|
||||
|
||||
<Default {...Astro.props}><slot /></Default>
|
||||
|
||||
{challengeNumber && <ChallengeFooter {...Astro.props} />}
|
||||
|
||||
<div class="border-t"></div>
|
||||
|
||||
{ renderCommentSection
|
||||
?
|
||||
<script src="https://giscus.app/client.js"
|
||||
data-repo="tomalaforge/angular-challenges"
|
||||
data-repo-id="R_kgDOIXXIfw"
|
||||
data-category="Announcements"
|
||||
data-category-id="DIC_kwDOIXXIf84CSZF_"
|
||||
data-mapping="title"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="bottom"
|
||||
data-theme="preferred_color_scheme"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async>
|
||||
</script>
|
||||
: ``}
|
||||
{ renderCommentSection && <CommentSection /> }
|
||||
|
||||
<style>
|
||||
.border-t {
|
||||
border-top: solid 1px rgb(36, 37, 38);
|
||||
margin: 3rem 0px;
|
||||
.author {
|
||||
margin-top: -1rem;
|
||||
font-size: var(--sl-text-xs);
|
||||
color: var(--sl-color-gray-3);
|
||||
}
|
||||
|
||||
</style>
|
||||
39
docs/src/components/PageTitle.astro
Normal file
39
docs/src/components/PageTitle.astro
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
import type { Props } from '@astrojs/starlight/props';
|
||||
import Default from '@astrojs/starlight/components/PageTitle.astro';
|
||||
|
||||
const challengeNumber = Astro.props.entry.data.challengeNumber;
|
||||
---
|
||||
|
||||
<div class="page-title-content">
|
||||
<Default {...Astro.props}><slot /></Default>
|
||||
{challengeNumber && <div class="chip">Challenge #{challengeNumber}</div> }
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.page-title-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1010px) {
|
||||
.page-title-content {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.chip {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: var(--color-chip-border);
|
||||
border-radius: 6px;
|
||||
padding: 2px 8px;
|
||||
background-color: var(--color-chip);
|
||||
color: var(--sl-color-text);
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
16
docs/src/components/VideoButton.astro
Normal file
16
docs/src/components/VideoButton.astro
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
|
||||
const { link, alt, flag } = Astro.props;
|
||||
const isFR = flag === 'FR';
|
||||
---
|
||||
|
||||
<a
|
||||
href={link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt={alt}>
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"></path></svg>
|
||||
Video
|
||||
{isFR && <span class="flag">🇫🇷<span>}
|
||||
</a>
|
||||
|
||||
@@ -5,8 +5,18 @@ export const collections = {
|
||||
docs: defineCollection({
|
||||
schema: (ctx) =>
|
||||
docsSchema()(ctx).extend({
|
||||
// Add a new optional field to the schema.
|
||||
noCommentSection: z.boolean().optional(),
|
||||
noCommentSection: z.boolean().optional().default(false),
|
||||
challengeNumber: z.union([z.number(), z.boolean()]).default(false),
|
||||
author: z.string().optional(),
|
||||
command: z.string().optional(),
|
||||
blogLink: z.string().optional(),
|
||||
videoLink: z
|
||||
.object({
|
||||
link: z.string(),
|
||||
alt: z.string(),
|
||||
flag: z.enum(['FR']).optional(),
|
||||
})
|
||||
.optional(),
|
||||
}),
|
||||
}),
|
||||
i18n: defineCollection({ type: 'data', schema: i18nSchema() }),
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟠 Optimize Change Detection
|
||||
description: Challenge 12 about optimizing the number of change detection cycle while scrolling
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 12
|
||||
command: scroll-cd
|
||||
sidebar:
|
||||
order: 107
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #12</div>
|
||||
|
||||
## Information
|
||||
|
||||
In Angular, there is a library called <b>Zone.js</b> that performs a lot of magic to simplify a developer's life. Zone.js monkey patches all DOM events so that it will recheck and rerender the view when something has changed inside the application. The developer doesn't have to manually trigger change detection.
|
||||
@@ -35,26 +36,3 @@ Your goal for this challenge is to avoid all unnecessary change detection cycles
|
||||
## 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.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve scroll-cd`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:12</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A12+label%3Aanswer"
|
||||
alt="Optimize Change Detection community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A{challenge number}+label%3A"answer+author"'
|
||||
alt="Optimize Change Detection solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟢 Default vs OnPush
|
||||
description: Challenge 34 is about learning the difference between Default and OnPush Change Detection Strategy.
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 34
|
||||
command: performance-default-onpush
|
||||
sidebar:
|
||||
order: 7
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #34</div>
|
||||
|
||||
## Information
|
||||
|
||||
In this challenge, we will explore the differences and impacts of using `ChangeDetectionStrategy.Default` versus `ChangeDetectionStrategy.OnPush`.
|
||||
@@ -52,26 +53,3 @@ Use `ChangeDetectionStrategy.OnPush` but this will not be enough.
|
||||
Create smaller components to better separate the input field from the list.
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve performance-default-onpush`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:34</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A34+label%3Aanswer"
|
||||
alt="Default vs OnPush community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A34+label%3A"answer+author"'
|
||||
alt="Default vs OnPush solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟢 Memoization
|
||||
description: Challenge 35 is about learning how pure pipe works
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 35
|
||||
command: performance-memoized
|
||||
sidebar:
|
||||
order: 8
|
||||
---
|
||||
@@ -45,26 +48,3 @@ The goal of this challenge is to understand what is causing this latency and to
|
||||
Use `Pipes` to memoize the Fibonnaci computation.
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve performance-memoized`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:35</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A35+label%3Aanswer"
|
||||
alt="Memoization community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A35+label%3A"answer+author"'
|
||||
alt="Memoization solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟢 NgFor Optimization
|
||||
description: Challenge 36 is about learning how trackby works
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 36
|
||||
command: performance-ngfor-optimize
|
||||
sidebar:
|
||||
order: 13
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #36</div>
|
||||
|
||||
## 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).
|
||||
@@ -28,26 +29,3 @@ If you need more information about `NgFor`, I invite you to read the [documentat
|
||||
## Statement
|
||||
|
||||
The goal of this challenge is to understand what is causing this DOM refresh and to solve it.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve performance-ngfor-optimize`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:36</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A36+label%3Aanswer"
|
||||
alt="NgFor Optimization community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A36+label%3A"answer+author"'
|
||||
alt="NgFor Optimization solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
---
|
||||
title: 🟠 Optimize Big List
|
||||
description: Challenge 37 is about learning how virtualization optimize big list rendering
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 37
|
||||
command: performance-ngfor-biglist
|
||||
sidebar:
|
||||
order: 117
|
||||
badge: New
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #37</div>
|
||||
|
||||
## 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.
|
||||
@@ -33,26 +34,3 @@ The goal of this challenge is to implement a better alternative to display big l
|
||||
If you're unsure where to begin, I recommend reading the [Angular CDK virtualization documentation](https://material.angular.io/cdk/scrolling/overview)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve performance-ngfor-biglist`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:37</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A37+label%3Aanswer"
|
||||
alt="NgFor optimize big list community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A37+label%3A"answer+author"'
|
||||
alt="NgFor optimize big list solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
---
|
||||
title: 🟢 Projection
|
||||
description: Challenge 1 is about learning how to project DOM element through components
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 1
|
||||
command: projection
|
||||
blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5
|
||||
videoLink:
|
||||
link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq
|
||||
alt: Projection video by Arthur Lannelucq
|
||||
flag: FR
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #1</div>
|
||||
|
||||
## Information
|
||||
|
||||
In Angular, content projection is a powerful technique for creating highly customizable components. Utilizing and understanding the concepts of <b>ng-content</b> and <b>ngTemplateOutlet</b> can sighificantly enhance your ability to create shareable components.
|
||||
@@ -29,43 +35,3 @@ While the application works, the developer experience is far from being optimal.
|
||||
- The `NgFor` directive must be declared and remain inside the `CardComponent`. You might be tempted to move it to the `CardComponent` but avoid doing so.
|
||||
- `CardComponent` should not contain any `NgIf` or `NgSwitch`.
|
||||
- CSS: try to avoid using `::ng-deep`. Find a better way to handle CSS styling.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve projection`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:1</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A1+label%3Aanswer"
|
||||
alt="Projection community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A1+label%3A"answer+author"'
|
||||
alt="Projection solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href="https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Projection blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Projection video by Arthur Lannelucq">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"></path></svg>
|
||||
Video
|
||||
<span class="flag">🇫🇷<span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🔴 Utility Wrapper Pipe
|
||||
description: Challenge 10 is about creating a pipe to wrap utilities
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 10
|
||||
command: pipe-hard
|
||||
sidebar:
|
||||
order: 202
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #10</div>
|
||||
|
||||
The goal of this serie of 3 pipe challenges is to master PIPES in Angular.
|
||||
|
||||
Pure pipe are a very useful way to transform data from your template. The difference between calling a function and a pipe is that pure pire are memoized. So they won't be recalculated every change detection cycle if the inputs hasn't changed.
|
||||
@@ -22,26 +23,3 @@ In this third exercice, you want to access utils functions. Currently we cannot
|
||||
## Constraints:
|
||||
|
||||
- must be strongly typed
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve pipe-hard`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:10</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A10+label%3Aanswer"
|
||||
alt="Utility Wrapper Pipe community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A10+label%3A"answer+author"'
|
||||
alt="Utility Wrapper Pipe solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟠 Highly Customizable CSS
|
||||
description: Challenge 13 is about creating highly customizable CSS styles
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 13
|
||||
command: styling
|
||||
sidebar:
|
||||
order: 104
|
||||
---
|
||||
@@ -24,26 +27,3 @@ In this challenge, you will need to use both CSS variables and :host-context to
|
||||
## Constraints:
|
||||
|
||||
- In your final submission, your component should not contain any lines of code. All styling should be handled within the decorator _(or external css files if you prefer)_
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve styling`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:13</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A13+label%3Aanswer"
|
||||
alt="Highly Customizable CSS community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A13+label%3A"answer+author"'
|
||||
alt="Highly Customizable CSS solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🔴 Master Dependancy Injection
|
||||
description: Challenge 16 is about masjering how dependancy injection works
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 16
|
||||
command: di
|
||||
sidebar:
|
||||
order: 203
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #16</div>
|
||||
|
||||
## Information
|
||||
|
||||
To successfully complete this challenge, you will need to have a good understanding of how Dependency Injection works inside Angular.
|
||||
@@ -27,26 +28,3 @@ One way to achieve this is by adding a second argument to the pipe, but this is
|
||||
|
||||
- You cannot modify the pipe.
|
||||
- You cannot wrap the row inside a component, as this will break the layout.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve di`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:16</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A16+label%3Aanswer"
|
||||
alt="Master Dependancy Injection community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A16+label%3A"answer+author"'
|
||||
alt="Master Dependancy Injection solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟢 Anchor Navigation
|
||||
description: Challenge 21 is about navigating inside the page with anchor
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 21
|
||||
command: anchor-scrolling
|
||||
sidebar:
|
||||
order: 4
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #21</div>
|
||||
|
||||
## 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.
|
||||
@@ -19,26 +20,3 @@ You begin with an application that has basic navigation and anchor navigation in
|
||||
|
||||
- Your task is to refactor this application to use the built-in navigation tool to better fit within the Angular Framework. You can explore the router, but it's better to stay within the template and use the `RouterLink` directive.
|
||||
- To improve the user experience, add smooth scrolling.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve anchor-scrolling`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:21</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A21+label%3Aanswer"
|
||||
alt="Anchor Navigation community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A21+label%3A"answer+author"'
|
||||
alt="Anchor Navigation solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
---
|
||||
title: 🟢 @RouterInput()
|
||||
description: Challenge 22 is about using the @Input decorator to retreive router params.
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 22
|
||||
command: router-input
|
||||
blogLink: https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617
|
||||
sidebar:
|
||||
order: 5
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #22</div>
|
||||
|
||||
## Information
|
||||
|
||||
In this application, we retrieve three pieces of information inside our `TestComponent` provided by the router:
|
||||
@@ -23,34 +25,3 @@ In version 16, Angular introduced a new `Input` that can listen to route data. Y
|
||||
## Statement
|
||||
|
||||
The goal of this exercice is to refactor the code to use the new `RouterInput` strategy.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve router-input`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:22</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A22+label%3Aanswer"
|
||||
alt="@RouterInput() community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A22+label%3A"answer+author"'
|
||||
alt="@RouterInput() solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/ngconf/accessing-route-params-in-angular-1f8e12770617'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="@RouterInput() blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟠 Directive Enhancement
|
||||
description: Challenge 3 is about enhancing a built-in directive
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 3
|
||||
command: ngfor-enhancement
|
||||
blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c
|
||||
sidebar:
|
||||
order: 101
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #3</div>
|
||||
|
||||
## Information
|
||||
|
||||
Directive is a very powerful tool only offered by the Angular framework. You can apply the DRY principal by having shared logic inside a directive and applying it to any component you want.
|
||||
@@ -42,34 +44,3 @@ We want to get rid of the ng-container by writing :
|
||||
```
|
||||
|
||||
The goal is to **improve the ngFor directive**
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve ngfor-enhancement`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:3</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A3+label%3Aanswer"
|
||||
alt="Directive Enhancement community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A3+label%3A"answer+author"'
|
||||
alt="Directive Enhancement solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Directive Enhancement blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🔴 Interoperability Rxjs/Signal
|
||||
description: Challenge 30 is about learning how to mix signal with Rxjs
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 30
|
||||
command: interop-rxjs-signal
|
||||
sidebar:
|
||||
order: 204
|
||||
---
|
||||
@@ -16,26 +19,3 @@ WIP: The following documentation will be reviewed and improved. However, you can
|
||||
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
|
||||
Start the project by running: `npx nx serve interop-rxjs-signal`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:30</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A30+label%3Aanswer"
|
||||
alt="Interoperability Rxjs/Signal community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A30+label%3A"answer+author"'
|
||||
alt="Interoperability Rxjs/Signal solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟢 Module to Standalone
|
||||
description: Challenge 31 is about migrating a module based application to a standalone application.
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 31
|
||||
command: module-to-standalone
|
||||
sidebar:
|
||||
order: 6
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #31</div>
|
||||
|
||||
## 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.
|
||||
@@ -24,26 +25,3 @@ After completing this challenge, standalone components will no longer hold any s
|
||||
## Statement
|
||||
|
||||
The goal of this challenge is to migrate your application from module based components to standalone components.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve module-to-standalone`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:31</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A31+label%3Aanswer"
|
||||
alt="Module to Standalone community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A31+label%3A"answer+author"'
|
||||
alt="Module to Standalone solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟠 Change Detection Bug
|
||||
description: Challenge 32 is about debugging an application that has issue when change detection is triggered
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 32
|
||||
command: bug-cd
|
||||
blogLink: https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629
|
||||
sidebar:
|
||||
order: 105
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #32</div>
|
||||
|
||||
:::note
|
||||
This challenge is inspired by a real-life example that I simplified to create this nice challenge.
|
||||
:::
|
||||
@@ -37,34 +39,3 @@ The goal of the challenge is to debug this application and make it work.
|
||||
If you open the [`RouterLinkActive` source code](https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link_active.ts) and go to **line 196**, Angular is calling `this.cdr.markForCheck` inside a microTask which triggers a new CD cycle. If you comment out this line, the application loads again, however the bug is not inside the Angular Framework. 😅😯
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve bug-cd`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:32</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A32+label%3Aanswer"
|
||||
alt="Change Detection Bug community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A32+label%3A"answer+author"'
|
||||
alt="Change Detection Bug solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href="https://medium.com/ngconf/function-calls-inside-template-are-dangerous-15f9822a6629"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Change Detection Bug blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟠 Decoupling Components
|
||||
description: Challenge 33 is about decoupling two strongly coupled components using Injection Token
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 33
|
||||
command: decoupling
|
||||
sidebar:
|
||||
order: 106
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #33</div>
|
||||
|
||||
> 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.
|
||||
|
||||
@@ -32,26 +33,3 @@ The goal of this challenge is to find a way to decouple both Directives.
|
||||
<summary>Hint 1</summary>
|
||||
Carefully read the title of the challenge 😇
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve decoupling`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:33</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A33+label%3Aanswer"
|
||||
alt="Decoupling Components community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A33+label%3A"answer+author"'
|
||||
alt="Decoupling Components solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🔴 Typed ContextOutlet
|
||||
description: Challenge 4 is about strongly typing ngContextOutlet directives
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 4
|
||||
command: context-outlet-type
|
||||
blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6
|
||||
sidebar:
|
||||
order: 201
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #4</div>
|
||||
|
||||
## Information
|
||||
|
||||
Angular offer the static function **ngTemplateContextGuard** to strongly type structural directive.
|
||||
@@ -40,34 +42,3 @@ Currently we have the following piece of code.
|
||||
As we can see, student is of type "any". We want to infer the correct type.
|
||||
|
||||
But in this part, we can pass to ListComponent, a list of **any object**. And we still want the correct type to be infered.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve context-outlet-type`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:4</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A4+label%3Aanswer"
|
||||
alt="Typed ContextOutlet community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A4+label%3A"answer+author"'
|
||||
alt="Typed ContextOutlet solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Typed ContextOutlet blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟢 Crud application
|
||||
description: Challenge 5 is about refactoring a crud application
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 5
|
||||
command: crud
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #5</div>
|
||||
|
||||
## Information
|
||||
|
||||
Communicating and having a global/local state in sync with your backend is the heart of any application. You will need to master those following best practises to build strong and reliable Angular Application.
|
||||
@@ -54,26 +55,3 @@ this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]
|
||||
|
||||
- Use the **component store of ngrx** as a local state of your component. _(or any other 3rd Party lib)_
|
||||
- Have a **localize** 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)_
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve crud`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:5</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A5+label%3Aanswer"
|
||||
alt="Crud application community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A5+label%3A"answer+author"'
|
||||
alt="Crud application solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟠 Structural Directive
|
||||
description: Challenge 6 is about creating a structural directive to handle permissions
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 6
|
||||
command: permissions
|
||||
blogLink: https://medium.com/@thomas.laforge/create-a-custom-structural-directive-to-manage-permissions-like-a-pro-11a1acad30ad
|
||||
sidebar:
|
||||
order: 102
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #6</div>
|
||||
|
||||
## 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.
|
||||
@@ -55,34 +57,3 @@ You should end up with something like below:
|
||||
## Step 2
|
||||
|
||||
In **Routes.ts**, route all user to the correct **DashboardComponent** using **CanMatch** guard.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve permissions`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:6</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A6+label%3Aanswer"
|
||||
alt="Structural Directive community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A6+label%3A"answer+author"'
|
||||
alt="Structural Directive solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/@thomas.laforge/create-a-custom-structural-directive-to-manage-permissions-like-a-pro-11a1acad30ad'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Structural Directive blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟢 Pure Pipe
|
||||
description: Challenge 8 is about creating a pure pipe
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 8
|
||||
command: pipe-easy
|
||||
blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d
|
||||
sidebar:
|
||||
order: 3
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #8</div>
|
||||
|
||||
The goal of this serie of 3 pipe challenges is to master PIPES in Angular.
|
||||
|
||||
Pure pipe are a very useful way to transform data from your template. The difference between calling a function and a pipe is that pure pire are memoized. So they won't be recalculated every change detection cycle if the inputs hasn't changed.
|
||||
@@ -22,34 +24,3 @@ In this first exercice, you add calling a simple function inside your template.
|
||||
## Constraints:
|
||||
|
||||
- must be strongly typed
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve pipe-easy`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:8</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A8+label%3Aanswer"
|
||||
alt="Pure Pipe community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A8+label%3A"answer+author"'
|
||||
alt="Pure Pipe solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Pure Pipe blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟠 Wrap Function Pipe
|
||||
description: Challenge 9 is about creating a pipe to wrap component fonctions
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 9
|
||||
command: pipe-intermediate
|
||||
blogLink: https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d
|
||||
sidebar:
|
||||
order: 103
|
||||
---
|
||||
@@ -23,34 +27,3 @@ The goal is to create a `wrapFn` pipe to wrap your callback function though a pi
|
||||
## Constraints:
|
||||
|
||||
- must be strongly typed
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve pipe-intermediate`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:9</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A9+label%3Aanswer"
|
||||
alt="Wrap Function Pipe community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A9+label%3A"answer+author"'
|
||||
alt="Wrap Function Pipe solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/ngconf/boost-your-apps-performance-by-wrapping-your-functions-inside-a-pipe-7e889a901d1d'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Wrap Function Pipe blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟠 Effect vs Selector
|
||||
description: Challenge 2 is about learning the difference between effects and selectors in NgRx
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 2
|
||||
command: ngrx-1
|
||||
blogLink: https://medium.com/@thomas.laforge/ngrx-effect-vs-reducer-vs-selector-58337ab59043
|
||||
sidebar:
|
||||
order: 113
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #2</div>
|
||||
|
||||
For this exercice, you will have a dashboard of activities displaying the name, the main teacher and a list of subtitutes.
|
||||
|
||||
## Information
|
||||
@@ -30,34 +32,3 @@ You will have to Refactor this working example of a dashboard of activities.
|
||||
- Only **one action** should be dispatched from a component
|
||||
- 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 state might not be useful, it's only a **derived state** of existing state.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve ngrx-1`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:2</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A2+label%3Aanswer"
|
||||
alt="Effect vs Selector community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A2+label%3A"answer+author"'
|
||||
alt="Effect vs Selector solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/@thomas.laforge/ngrx-effect-vs-reducer-vs-selector-58337ab59043'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Effect vs Selector blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🔴 Power of Effect
|
||||
description: Challenge 7 is about creating an Ngrx effect with another Rxjs Hot observable
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 7
|
||||
command: ngrx-notification
|
||||
sidebar:
|
||||
order: 206
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #7</div>
|
||||
|
||||
## Information
|
||||
|
||||
NgRx Effect is a very powerful library develop by the NgRx team. Effects subscribe to a HOT Observable and listen to any event dispatch from any place inside the application.
|
||||
@@ -33,26 +34,3 @@ create one ngrx effect, or component store effect for each push type, and implem
|
||||
|
||||
load your effect only when necessary.
|
||||
the application contain a root route, a lazy loaded route and a component with a local state (implemented with Component store)
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve ngrx-notification`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:7</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A7+label%3Aanswer"
|
||||
alt="Power of Effect community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A7+label%3A"answer+author"'
|
||||
alt="Power of Effect solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 🔴 Extend Lib Generator
|
||||
description: Challenge 25 is about creating a Nx generator to extend the built-in Library Generator
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 25
|
||||
sidebar:
|
||||
order: 207
|
||||
---
|
||||
@@ -53,22 +55,3 @@ export default {
|
||||
`eslintrc.json`
|
||||
|
||||
add this rule `"@typescript-eslint/member-ordering": "off"` inside the rules properties of ts files.
|
||||
|
||||
---
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:25</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A25+label%3Aanswer"
|
||||
alt="Extend Lib Generator community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A25+label%3A"answer+author"'
|
||||
alt="Extend Lib Generator solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 🟠 Component Generator
|
||||
description: Challenge 26 is about creating a Nx generator to create a custom component
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 26
|
||||
sidebar:
|
||||
order: 116
|
||||
---
|
||||
@@ -141,22 +143,3 @@ export interface User {
|
||||
name: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:26</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A26+label%3Aanswer"
|
||||
alt="Component Generator community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A26+label%3A"answer+author"'
|
||||
alt="Component Generator solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 🟢 Custom Eslint Rule
|
||||
description: Challenge 27 is about creating a custom Eslint Rule to forbid enums
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 27
|
||||
sidebar:
|
||||
order: 12
|
||||
---
|
||||
@@ -22,22 +24,3 @@ To test the rule inside your project, add `"@nrwl/nx/workspace/forbidden-enum":
|
||||
To assist you with AST (Abstract Syntax Tree) definitions, you can visit the [AST explorer](https://astexplorer.net/) and use JavaScript, @typescript-eslint/parser, and Eslint-v8 as the transformation method. However, please note that you will only get the type information there. The transformation function may not work for TypeScript types since the editor is in JavaScript.
|
||||
|
||||
You can also check this [repo](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/src/rules) for eslint rule examples.
|
||||
|
||||
---
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:27</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A27+label%3Aanswer"
|
||||
alt="Custom Eslint Rule community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A27+label%3A"answer+author"'
|
||||
alt="Custom Eslint Rule solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟠 High Order Operator Bug
|
||||
description: Challenge 11 is about resolving a Rxjs bug because of high order operators
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 11
|
||||
command: rxjs-pipe-bu
|
||||
sidebar:
|
||||
order: 114
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #11</div>
|
||||
|
||||
Let's dive inside the wonderful word of RxJs.
|
||||
|
||||
This challenge is inspired by a real-life example.
|
||||
@@ -30,26 +31,3 @@ We can only pass one object to our DB for deletion at the time. The DB will resp
|
||||
The QA team reports a **bug**. The UI shows **All [topic] have been deleted** all the time, even if some deletions fail.
|
||||
|
||||
👉 Spot the bug and correct it.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve rxjs-pipe-bug`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:11</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A11+label%3Aanswer"
|
||||
alt="High Order Operator Bug community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A11+label%3A"answer+author"'
|
||||
alt="High Order Operator Bug solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟢 Race Condition
|
||||
description: Challenge 14 is about race condition in Rxjs
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 14
|
||||
command: rxjs-race-condition
|
||||
sidebar:
|
||||
order: 11
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #14</div>
|
||||
|
||||
## 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.
|
||||
@@ -28,26 +29,3 @@ Correct your application to pass the test
|
||||
|
||||
HEADLESS : `npx nx component-test rxjs-race-condition`
|
||||
WATCH MODE : `npx nx component-test rxjs-race-condition --watch`
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve rxjs-race-condition`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:14</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A14+label%3Aanswer"
|
||||
alt="Race Condition community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A14+label%3A"answer+author"'
|
||||
alt="Race Condition solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟠 Router
|
||||
description: Challenge 17 is about testing the router
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 17
|
||||
command: testing-router-outlet
|
||||
sidebar:
|
||||
order: 108
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #17</div>
|
||||
|
||||
## Information
|
||||
|
||||
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.
|
||||
@@ -22,26 +23,3 @@ The goal is to test multiple behaviors of the application described in each test
|
||||
:::note
|
||||
I have created some `it` blocks but feel free to add more tests if you want.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-router-outlet`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:17</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A17+label%3Aanswer"
|
||||
alt="Router community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A17+label%3A"answer+author"'
|
||||
alt="Router solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟠 Nested Components
|
||||
description: Challenge 18 is about testing nested components
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 18
|
||||
command: testing-nested
|
||||
sidebar:
|
||||
order: 109
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #18</div>
|
||||
|
||||
## Information
|
||||
|
||||
We have a small application that sends a title, typed into an input to a fake backend.
|
||||
@@ -26,26 +27,3 @@ The goal is to test multiple behaviors of the application describe inside each t
|
||||
:::note
|
||||
I have created some `it` blocks but feel free to add more tests if you want.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-nested`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:18</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A18+label%3Aanswer"
|
||||
alt="Nested Components community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A18+label%3A"answer+author"'
|
||||
alt="Nested Components solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟠 Input Output
|
||||
description: Challenge 19 is about testing inputs and ouputs
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 19
|
||||
command: testing-input-output
|
||||
sidebar:
|
||||
order: 110
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #19</div>
|
||||
|
||||
## Information:
|
||||
|
||||
We have a small counter application that increments or decrements a number. The `CounterComponent` takes an initial value as an `@Input` and emits the result of the counter as an `@Output` when we click on the **Send** button. Since we are testing our component as a black box, we only have access to our inputs and listen to the output values. <b>We should not rely on any internal implementation details!!!</b>
|
||||
@@ -24,26 +25,3 @@ The goal is to test multiple behaviors of the application describe inside each t
|
||||
:::note
|
||||
I have created some `it` blocks but feel free to add more tests if you want.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-input-output`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:19</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A19+label%3Aanswer"
|
||||
alt="Input Output community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A19+label%3A"answer+author"'
|
||||
alt="Input Output solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟠 Modal
|
||||
description: Challenge 20 is about testing modals
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 20
|
||||
command: testing-modal
|
||||
sidebar:
|
||||
order: 111
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #20</div>
|
||||
|
||||
## Information:
|
||||
|
||||
In this small application, you have an input prompting you to enter a name, and a **Confirm** button to submit your form.
|
||||
@@ -28,26 +29,3 @@ The goal is to test multiple behaviors of the application describe inside each t
|
||||
:::note
|
||||
I have created some `it` blocks but feel free to add more tests if you want.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-modal`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:20</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A20+label%3Aanswer"
|
||||
alt="Modal community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A20+label%3A"answer+author"'
|
||||
alt="Modal solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟢 Harness
|
||||
description: Challenge 23 is about testing with component harnesses
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 23
|
||||
command: testing-harness
|
||||
sidebar:
|
||||
order: 9
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #23</div>
|
||||
|
||||
## 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.
|
||||
@@ -21,26 +22,3 @@ The goal is to test the functionality of `child.component.ts`. I have prepared a
|
||||
|
||||
Documentation for CDK Component Harness is [here](https://material.angular.io/cdk/test-harnesses/overview#api-for-test-authors)
|
||||
Documentation for Angular Material component is [here](https://material.angular.io/components/button/overview)
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-harness`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:23</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A23+label%3Aanswer"
|
||||
alt="Harness community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A23+label%3A"answer+author"'
|
||||
alt="Harness solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
---
|
||||
title: 🟠 Harness Creation
|
||||
description: Challenge 24 is about creating a component harness.
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 24
|
||||
command: create-harness
|
||||
sidebar:
|
||||
order: 112
|
||||
---
|
||||
@@ -9,8 +12,6 @@ sidebar:
|
||||
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 #24</div>
|
||||
|
||||
## 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.
|
||||
@@ -45,26 +46,3 @@ Lastly, you will need to create the test suite for `app.component`. Some default
|
||||
> Angular Material documentation can be found [here](https://material.angular.io/cdk/test-harnesses/overview)
|
||||
|
||||
Good luck !!! 💪
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve create-harness`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:24</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A24+label%3Aanswer"
|
||||
alt="Harness Creation community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A24+label%3A"answer+author"'
|
||||
alt="Harness Creation solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🟢 Checkbox
|
||||
description: Challenge 28 is about testing a simple checkbox
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 10
|
||||
command: testing-checkbox
|
||||
sidebar:
|
||||
order: 10
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #28</div>
|
||||
|
||||
## 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.
|
||||
@@ -22,26 +23,3 @@ The main functions to remember are as follows:
|
||||
## Statement
|
||||
|
||||
The goal of this challenge is not to submit an answer, but you can if you want. It's more about using the debugging API to play around. These tools will be of great help for the upcoming testing challenges.
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-checkbox`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:28</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A28+label%3Aanswer"
|
||||
alt="Checkbox community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A28+label%3A"answer+author"'
|
||||
alt="Checkbox solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: 🔴 Real-life Application
|
||||
description: Challenge 29 is about testing a real-life application
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 29
|
||||
command: testing-todos-list
|
||||
sidebar:
|
||||
order: 205
|
||||
---
|
||||
|
||||
<div class="chip">Challenge #29</div>
|
||||
|
||||
## Information:
|
||||
|
||||
This application presents a greater challenge because it closely resembles a real-life application that you might encounter in your day-to-day activities as an Angular developer. What makes it more difficult is the need to handle asynchronous tasks and create appropriate mocks.
|
||||
@@ -30,26 +31,3 @@ The goal is to test multiple behaviors of the application describe inside each t
|
||||
:::note
|
||||
I have created some `it` blocks but feel free to add more tests if you want.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve testing-todos-list`.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:29</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A29+label%3Aanswer"
|
||||
alt="Real-life Application community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A29+label%3A"answer+author"'
|
||||
alt="Real-life Application solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
title: 🟠 Function Overload
|
||||
description: Challenge 15 is about creating overload functions
|
||||
author: Thomas Laforge
|
||||
challengeNumber: 15
|
||||
command: overload
|
||||
blogLink: https://medium.com/ngconf/function-overloading-in-typescript-8236706b2c05
|
||||
sidebar:
|
||||
order: 115
|
||||
---
|
||||
@@ -9,8 +13,6 @@ sidebar:
|
||||
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 #15</div>
|
||||
|
||||
## Information
|
||||
|
||||
Angular uses TypeScript, and mastering TypeScript can help you avoid runtime errors by catching them at compile time.
|
||||
@@ -24,34 +26,3 @@ To achieve this, we will use overload functions.
|
||||
## Statement
|
||||
|
||||
- Use function overload
|
||||
|
||||
---
|
||||
|
||||
:::note
|
||||
Start the project by running: `npx nx serve overload``.
|
||||
:::
|
||||
|
||||
:::tip[Reminder]
|
||||
Your PR title must start with <b>Answer:15</b>.
|
||||
:::
|
||||
|
||||
<div class="article-footer">
|
||||
<a
|
||||
href="https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A15+label%3Aanswer"
|
||||
alt="Function Overload community solutions">
|
||||
❖ Community Answers
|
||||
</a>
|
||||
<a
|
||||
href='https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A15+label%3A"answer+author"'
|
||||
alt="Function Overload solution author">
|
||||
▶︎ Author Answer
|
||||
</a>
|
||||
<a
|
||||
href='https://medium.com/ngconf/function-overloading-in-typescript-8236706b2c05'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
alt="Function Overload blog article">
|
||||
<svg aria-hidden="true" class="astro-yzt5nm4y astro-lq7oo3uf" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"></path></svg>
|
||||
Blog Post
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -49,17 +49,6 @@
|
||||
margin: 0px 2px;
|
||||
}
|
||||
|
||||
.chip {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: var(--color-chip-border);
|
||||
border-radius: 6px;
|
||||
padding: 2px 8px;
|
||||
background-color: var(--color-chip);
|
||||
color: var(--sl-color-text);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.article-footer {
|
||||
margin-top: 3rem !important;
|
||||
display: flex;
|
||||
@@ -131,3 +120,7 @@ starlight-menu-button svg {
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* .content-panel {
|
||||
padding-top: 2px;
|
||||
} */
|
||||
|
||||
Reference in New Issue
Block a user