fix(docs-infra): update docs-alert and tests (#60829)

Before this commit, the docs-alert tests were failing. This also ensures that `NOTE:`, `TIP:` and others are always capitalized.

(cherry picked from commit ab5986dd5685d36e209972916cddb9dca8e0a557)

PR Close #60829
This commit is contained in:
Alan Agius
2025-04-10 12:56:15 +00:00
committed by kirjs
parent d39e09da41
commit 77c60414a2
83 changed files with 172 additions and 178 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ cd angular
yarn
# Build and run local dev server
# Note: Initial build will take some time
# NOTE: Initial build will take some time
yarn docs
```
@@ -10,12 +10,12 @@ import {RendererThis, Token, TokenizerThis, Tokens} from 'marked';
/** Enum of all available alert severities. */
export enum AlertSeverityLevel {
Note = 'NOTE',
Tip = 'TIP',
NOTE = 'NOTE',
TIP = 'TIP',
TODO = 'TODO',
QUESTION = 'QUESTION',
Summary = 'SUMMARY',
TLDR = 'TLDR',
SUMMARY = 'SUMMARY',
TLDR = 'TL;DR',
CRITICAL = 'CRITICAL',
IMPORTANT = 'IMPORTANT',
HELPFUL = 'HELPFUL',
@@ -39,14 +39,14 @@ export const docsAlertExtension = {
level: 'block' as const,
tokenizer(this: TokenizerThis, src: string): DocsAlertToken | undefined {
let match: DocsAlert | undefined;
for (let level in AlertSeverityLevel) {
for (const key of Object.keys(AlertSeverityLevel)) {
// Capture group 1: all alert text content after the severity level
const rule = new RegExp('^s*' + level + ': (.*?)\n(\n|$)', 's');
const rule = new RegExp('^s*' + key + ': (.*?)\n(\n|$)', 's');
const possibleMatch = rule.exec(src);
if (possibleMatch?.[1]) {
match = {
severityLevel: level,
severityLevel: key,
alert: possibleMatch,
};
}
@@ -57,12 +57,11 @@ export const docsAlertExtension = {
type: 'docs-alert',
raw: match.alert[0],
body: match.alert[1].trim(),
severityLevel: match.severityLevel,
severityLevel: match.severityLevel.toLowerCase(),
tokens: [],
};
token.body = `**${
token.severityLevel === AlertSeverityLevel.TLDR ? 'TL;DR' : token.severityLevel
}:** ${token.body}`;
token.body = `**${AlertSeverityLevel[match.severityLevel as keyof typeof AlertSeverityLevel]}:** ${token.body}`;
this.lexer.blockTokens(token.body, token.tokens);
return token;
}
@@ -1,13 +1,13 @@
Note: Use Note for ancillary/additional information that's not _essential_ to the main text.
NOTE: Use Note for ancillary/additional information that's not _essential_ to the main text.
This is a multiline note
Tip: Use Tip to call out a specific task/action users can perform, or a fact that plays directly into a task/action.
TIP: Use Tip to call out a specific task/action users can perform, or a fact that plays directly into a task/action.
TODO: Use TODO for incomplete documentation that you plan to expand soon. You can also assign the TODO, e.g. TODO(emmatwersky): Text.
QUESTION: Use Question to pose a question to the reader, kind of like a mini-quiz that they should be able to answer.
Summary: Use Summary to provide a two- or three-sentence synopsis of the page or section content, so readers can figure out whether this is the right place for them.
SUMMARY: Use Summary to provide a two- or three-sentence synopsis of the page or section content, so readers can figure out whether this is the right place for them.
TLDR: Use TLDR if you can provide the essential information about a page or section in a sentence or two.
@@ -24,15 +24,10 @@ describe('markdown to html', () => {
markdownDocument = JSDOM.fragment(await parseMarkdown(markdownContent, {}));
});
for (let level in AlertSeverityLevel) {
it(`should create a docs-alert for ${level}:`, () => {
const noteEl = markdownDocument.querySelector(`.docs-alert-${level.toLowerCase()}`);
// TLDR is written without a semi colon in the markdown, but is rendered
// with a colon, as such we have to adjust our expectation here.
if (level === AlertSeverityLevel.TLDR) {
level = 'TL;DR';
}
expect(noteEl?.textContent?.trim()).toMatch(`^${level}:`);
for (const [key, level] of Object.entries(AlertSeverityLevel)) {
it(`should create a docs-alert for ${key}:`, () => {
const noteEl = markdownDocument.querySelector(`.docs-alert-${key.toLowerCase()}`);
expect(noteEl?.textContent?.trim()).toMatch(new RegExp(`^${level}:`));
});
}
+2 -2
View File
@@ -81,7 +81,7 @@
5. The file is added to the TypeScript virtual file system, allowing the TypeScript web worker to provide diagnostics, autocomplete and type features for the new file. Also, exports from the new file are available in other files.
6. The new file is added as the last tab in the code editor and the new file can be edited.
Note: If the new file name matches a file that already exists but is hidden in the code editor, the content for that file will show up in the created file. An example for a file that always exists is `index.html`.
NOTE: If the new file name matches a file that already exists but is hidden in the code editor, the content for that file will show up in the created file. An example for a file that always exists is `index.html`.
### Deleting a file
@@ -90,7 +90,7 @@ Note: If the new file name matches a file that already exists but is hidden in t
3. The file is removed from the TypeScript virtual file system.
4. The file is removed from the code editor tabs.
Note: Some files can't be deleted to prevent users to break the app, being `src/main.ts`and `src/index.html`
NOTE: Some files can't be deleted to prevent users to break the app, being `src/main.ts`and `src/index.html`
### Switching a project
+1 -1
View File
@@ -21,7 +21,7 @@ When binding to ARIA attributes in Angular, you must use the `attr.` prefix. The
<button [attr.aria-label]="myActionLabel">…</button>
</docs-code>
Note: This syntax is only necessary for attribute *bindings*.
NOTE: This syntax is only necessary for attribute *bindings*.
Static ARIA attributes require no extra syntax.
<docs-code language="html">
@@ -1,6 +1,6 @@
# RxJS interop with component and directive outputs
Tip: This guide assumes you're familiar with [component and directive outputs](guide/components/outputs).
TIP: This guide assumes you're familiar with [component and directive outputs](guide/components/outputs).
The `@angular/rxjs-interop` package offers two APIs related to component and directive outputs.
@@ -15,7 +15,7 @@ import {outputFromObservable} from '@angular/core/rxjs-interop';
@Directive({/*...*/})
class Draggable {
pointerMoves$: Observable<PointerMovements> = listenToPointerMoves();
// Whenever `pointerMoves$` emits, the `pointerMove` event fires.
pointerMove = outputFromObservable(this.pointerMoves$);
}
@@ -61,7 +61,7 @@ This will serve your application with service worker support at http://localhost
With the server running on port `8080`, point your browser at `http://localhost:8080`.
Your application should load normally.
Tip: When testing Angular service workers, it's a good idea to use an incognito or private window in your browser to ensure the service worker doesn't end up reading from a previous leftover state, which can cause unexpected behavior.
TIP: When testing Angular service workers, it's a good idea to use an incognito or private window in your browser to ensure the service worker doesn't end up reading from a previous leftover state, which can cause unexpected behavior.
HELPFUL: If you are not using HTTPS, the service worker will only be registered when accessing the application on `localhost`.
@@ -90,10 +90,10 @@ withViewTransitions({
onViewTransitionCreated: ({transition}) => {
const router = inject(Router);
const targetUrl = router.getCurrentNavigation()!.finalUrl!;
// Skip the transition if the only thing
// Skip the transition if the only thing
// changing is the fragment and queryParams
const config = {
paths: 'exact',
const config = {
paths: 'exact',
matrixParams: 'exact',
fragment: 'ignored',
queryParams: 'ignored',
@@ -152,6 +152,6 @@ The view transition feature in the Angular router does not provide a way to dela
## Native View Transitions Alternative
Animating the transition between routes can also be done with the `@angular/animations` package.
Animating the transition between routes can also be done with the `@angular/animations` package.
The animation [triggers and transitions](/guide/animations/transition-and-triggers)
can be derived from the router state, such as the current URL or `ActivatedRoute`.
@@ -1,6 +1,6 @@
# Advanced component configuration
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
## ChangeDetectionStrategy
@@ -1,7 +1,7 @@
<docs-decorative-header title="Anatomy of a component" imgSrc="adev/src/assets/images/components.svg"> <!-- markdownlint-disable-line -->
</docs-decorative-header>
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Every component must have:
@@ -72,7 +72,7 @@ export class UserProfile { }
By default, Angular components are *standalone*, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgModule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details.
Important: In Angular versions before 19.0.0, the `standalone` option defaults to `false`.
IMPORTANT: In Angular versions before 19.0.0, the `standalone` option defaults to `false`.
### Showing components in a template
@@ -1,6 +1,6 @@
# Content projection with ng-content
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
You often need to create components that act as containers for different types of content. For
example, you may want to create a custom card component:
@@ -23,7 +23,7 @@ export class CustomCard {/* ... */}
export class CustomCard {/* ... */}
```
Tip: `<ng-content>` works similarly
TIP: `<ng-content>` works similarly
to [the native `<slot>` element](https://developer.mozilla.org/docs/Web/HTML/Element/slot),
but with some Angular-specific functionality.
@@ -1,6 +1,6 @@
# Using DOM APIs
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Angular handles most DOM creation, updates, and removals for you. However, you might rarely need to
directly interact with a component's DOM. Components can inject ElementRef to get a reference to the
@@ -1,6 +1,6 @@
# Component host elements
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Angular creates an instance of a component for every HTML element that matches the component's
selector. The DOM element that matches a component's selector is that component's **host element**.
@@ -1,6 +1,6 @@
# Inheritance
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Angular components are TypeScript classes and participate in standard JavaScript inheritance
semantics.
+9 -9
View File
@@ -1,8 +1,8 @@
# Accepting data with input properties
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Tip: If you're familiar with other web frameworks, input properties are similar to _props_.
TIP: If you're familiar with other web frameworks, input properties are similar to _props_.
When you use a component, you commonly want to pass some data to it. A component specifies the data that it accepts by declaring
**inputs**:
@@ -62,11 +62,11 @@ import {Component, input} from '@angular/core';
@Component({/*...*/})
export class CustomSlider {
// Declare an input named 'value' with a default value of zero.
// Declare an input named 'value' with a default value of zero.
value = input(0);
// Create a computed expression that reads the value input
label = computed(() => `The slider's value is ${this.value()}`);
label = computed(() => `The slider's value is ${this.value()}`);
}
</docs-code>
@@ -148,8 +148,8 @@ import {Component, input, booleanAttribute, numberAttribute} from '@angular/core
@Component({/*...*/})
export class CustomSlider {
disabled = input(false, {transform: booleanAttribute});
value = input(0, {transform: numberAttribute});
disabled = input(false, {transform: booleanAttribute});
value = input(0, {transform: numberAttribute});
}
</docs-code>
@@ -192,7 +192,7 @@ export class CustomSlider {
value = model(0);
increment() {
// Update the model input with a new value, propagating the value to any bindings.
// Update the model input with a new value, propagating the value to any bindings.
this.value.update(oldValue => oldValue + 10);
}
}
@@ -205,7 +205,7 @@ export class CustomSlider {
template: `<custom-slider [(value)]="volume" />`,
})
export class MediaControls {
// Create a writable signal for the `volume` local state.
// Create a writable signal for the `volume` local state.
volume = signal(0);
}
```
@@ -269,7 +269,7 @@ Avoid adding prefixes for component inputs like you would with component selecto
## Declaring inputs with the `@Input` decorator
Tip: While the Angular team recommends using the signal-based `input` function for new projects, the original decorator-based `@Input` API remains fully supported.
TIP: While the Angular team recommends using the signal-based `input` function for new projects, the original decorator-based `@Input` API remains fully supported.
You can alternatively declare component inputs by adding the `@Input` decorator to a property:
@@ -1,6 +1,6 @@
# Component Lifecycle
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
A component's **lifecycle** is the sequence of steps that happen between the component's creation
and its destruction. Each step represents a different part of Angular's process for rendering
+2 -2
View File
@@ -1,6 +1,6 @@
# Custom events with outputs
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Angular components can define custom events by assigning a property to the `output` function:
@@ -110,7 +110,7 @@ See [RxJS interop with component and directive outputs](ecosystem/rxjs-interop/o
## Declaring outputs with the `@Output` decorator
Tip: While the Angular team recommends using the `output` function for new projects, the
TIP: While the Angular team recommends using the `output` function for new projects, the
original decorator-based `@Output` API remains fully supported.
You can alternatively define custom events by assigning a property to a new `EventEmitter` and adding the `@Output` decorator:
@@ -1,6 +1,6 @@
# Programmatically rendering components
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
In addition to using a component directly in a template, you can also dynamically render components.
There are two main ways to dynamically render a component: in a template with `NgComponentOutlet`,
+5 -5
View File
@@ -1,6 +1,6 @@
# Referencing component children with queries
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
A component can define **queries** that find child elements and read values from their injectors.
@@ -88,9 +88,9 @@ export class CustomExpando {
toggleText = computed(() => this.toggle()?.text);
}
@Component({
@Component({
/* ... */
// CustomToggle is used inside CustomExpando as content.
// CustomToggle is used inside CustomExpando as content.
template: `
<custom-expando>
<custom-toggle>Show</custom-toggle>
@@ -186,7 +186,7 @@ Angular does not support CSS selectors as query locators.
### Queries and the injector tree
Tip: See [Dependency Injection](guide/di) for background on providers and Angular's injection tree.
TIP: See [Dependency Injection](guide/di) for background on providers and Angular's injection tree.
For more advanced cases, you can use any `ProviderToken` as a locator. This lets you locate elements based on component and directive providers.
@@ -259,7 +259,7 @@ In the example above, `CustomExpando` cannot find `<custom-toggle>` because it i
View queries do not have this option because they _always_ traverse into descendants.
## Decorator-based queries
Tip: While the Angular team recommends using the signal-based query function for new projects, the
TIP: While the Angular team recommends using the signal-based query function for new projects, the
original decorator-based query APIs remain fully supported.
You can alternatively declare queries by adding the corresponding decorator to a property. Decorator-based queries behave the same way as signal-based queries except as described below.
@@ -1,6 +1,6 @@
# Component selectors
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Every component defines
a [CSS selector](https://developer.mozilla.org/docs/Web/CSS/CSS_selectors) that determines how
+3 -3
View File
@@ -1,6 +1,6 @@
# Styling components
Tip: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular.
Components can optionally include CSS styles that apply to that component's DOM:
@@ -63,7 +63,7 @@ the [`:host`](https://developer.mozilla.org/docs/Web/CSS/:host)
and [`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context) pseudo
classes without
using [Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM).
During compilation, the framework transforms these pseudo classes into attributes so it doesn't
During compilation, the framework transforms these pseudo classes into attributes so it doesn't
comply with these native pseudo classes' rules at runtime (e.g. browser compatibility, specificity). Angular's
emulated encapsulation mode does not support any other pseudo classes related to Shadow DOM, such
as `::shadow` or `::part`.
@@ -97,7 +97,7 @@ Shadow DOM in your application before enabling this option.
This mode disables all style encapsulation for the component. Any styles associated with the
component behave as global styles.
Note: In `Emulated` and `ShadowDom` modes, Angular doesn't 100% guarantee that your component's styles will always override styles coming from outside it.
NOTE: In `Emulated` and `ShadowDom` modes, Angular doesn't 100% guarantee that your component's styles will always override styles coming from outside it.
It is assumed that these styles have the same specificity as your component's styles in case of collision.
## Defining styles in templates
@@ -90,7 +90,7 @@ In this way, `OldLogger` is an alias for `NewLogger`.
]
</docs-code>
Note: Ensure you do not alias `OldLogger` to `NewLogger` with `useClass`, as this creates two different `NewLogger` instances.
NOTE: Ensure you do not alias `OldLogger` to `NewLogger` with `useClass`, as this creates two different `NewLogger` instances.
### Factory providers: useFactory
@@ -65,7 +65,7 @@ class HeroListComponent {}
When you register a provider at the component level, you get a new instance of the service with each new instance of that component.
Note: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused.
NOTE: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused.
### At the application root level using `ApplicationConfig`
@@ -87,7 +87,7 @@ Then, in `main.ts`:
bootstrapApplication(AppComponent, appConfig)
</docs-code>
Note: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused.
NOTE: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused.
### `NgModule` based applications
@@ -96,20 +96,20 @@ Note: Declaring a service like this causes `HeroService` to always be included i
A service provided in a module is available to all declarations of the module, or to any other modules which share the same `ModuleInjector`.
To understand all edge-cases, see [Hierarchical injectors](guide/di/hierarchical-dependency-injection).
Note: Declaring a service using `providers` causes the service to be included in your application— even if the service is unused.
NOTE: Declaring a service using `providers` causes the service to be included in your application— even if the service is unused.
## Injecting/consuming a dependency
Use Angular's `inject` function to retrieve dependencies.
Use Angular's `inject` function to retrieve dependencies.
```ts
import {inject, Component} from 'angular/core';
import {inject, Component} from 'angular/core';
@Component({/* ... */})
export class UserProfile {
// You can use the `inject` function in property initializers.
private userClient = inject(UserClient);
constructor() {
// You can also use the `inject` function in a constructor.
const logger = inject(Logger);
@@ -309,7 +309,7 @@ export class HostComponent {
Since `HostComponent` has the `host` option , no matter what the parent of `HostComponent` might have as a `flower.emoji` value, the `HostComponent` will use tulip <code>&#x1F337;</code>.
### Modifiers with constructor injection
### Modifiers with constructor injection
Similarly as presented before, the behavior of constructor injection can be modified with `@Optional()`, `@Self()`, `@SkipSelf()` and `@Host()`.
@@ -590,7 +590,7 @@ Here, it has a value of dog <code>&#x1F436;</code>.
})
export class ChildComponent {
// inject services
flower = inject(FlowerService);
flower = inject(FlowerService);
animal = inject(AnimalService)
...
}
+1 -1
View File
@@ -2,7 +2,7 @@
"DI" is a design pattern and mechanism for creating and delivering some parts of an app to other parts of an app that require them.
</docs-decorative-header>
Tip: Check out Angular's [Essentials](essentials/dependency-injection) before diving into this comprehensive guide.
TIP: Check out Angular's [Essentials](essentials/dependency-injection) before diving into this comprehensive guide.
When you develop a smaller part of your system, like a module or a class, you may need to use features from other classes. For example, you may need an HTTP service to make backend calls. Dependency Injection, or DI, is a design pattern and mechanism for creating and delivering some parts of an application to other parts of an application that require them. Angular supports this design pattern and you can use it in your applications to increase flexibility and modularity.
+1 -1
View File
@@ -214,7 +214,7 @@ flowchart TB
end
```
Note: `NgModel` triggers a second change detection to avoid `ExpressionChangedAfterItHasBeenChecked` errors, because the value change originates in an input binding.
NOTE: `NgModel` triggers a second change detection to avoid `ExpressionChangedAfterItHasBeenChecked` errors, because the value change originates in an input binding.
### Mutability of the data model
@@ -267,7 +267,7 @@ The `FormBuilder` service has three methods: `control()`, `group()`, and `array(
In the preceding example, you use the `group()` method with the same object to define the properties in the model. The value for each control name is an array containing the initial value as the first item in the array.
Tip: You can define the control with just the initial value, but if your controls need sync or async validation, add sync and async validators as the second and third items in the array. Compare using the form builder to creating the instances manually.
TIP: You can define the control with just the initial value, but if your controls need sync or async validation, add sync and async validators as the second and third items in the array. Compare using the form builder to creating the instances manually.
<docs-code-multifile>
<docs-code header="src/app/profile-editor/profile-editor.component.ts (instances)" path="adev/src/content/examples/reactive-forms/src/app/profile-editor/profile-editor.component.1.ts" visibleRegion="formgroup-compare"/>
+1 -1
View File
@@ -65,7 +65,7 @@ export function loggingInterceptor(req: HttpRequest<unknown>, next: HttpHandlerF
}
</docs-code>
Tip: Interceptors naturally associate responses with their outgoing requests, because they transform the response stream in a closure that captures the request object.
TIP: Interceptors naturally associate responses with their outgoing requests, because they transform the response stream in a closure that captures the request object.
## Modifying requests
@@ -2,7 +2,7 @@
`HttpClient` has methods corresponding to the different HTTP verbs used to make requests, both to load data and to apply mutations on the server. Each method returns an [RxJS `Observable`](https://rxjs.dev/guide/observable) which, when subscribed, sends the request and then emits the results when the server responds.
Note: `Observable`s created by `HttpClient` may be subscribed any number of times and will make a new backend request for each subscription.
NOTE: `Observable`s created by `HttpClient` may be subscribed any number of times and will make a new backend request for each subscription.
Through an options object passed to the request method, various properties of the request and the returned response type can be adjusted.
@@ -20,7 +20,7 @@ http.get<Config>('/api/config').subscribe(config => {
Note the generic type argument which specifies that the data returned by the server will be of type `Config`. This argument is optional, and if you omit it then the returned data will have type `Object`.
Tip: When dealing with data of uncertain structure and potential `undefined` or `null` values, consider using the `unknown` type instead of `Object` as the response type.
TIP: When dealing with data of uncertain structure and potential `undefined` or `null` values, consider using the `unknown` type instead of `Object` as the response type.
CRITICAL: The generic type of request methods is a type **assertion** about the data returned by the server. `HttpClient` does not verify that the actual return data matches this type.
@@ -159,7 +159,7 @@ In addition to the response body or response object, `HttpClient` can also retur
Progress events are disabled by default (as they have a performance cost) but can be enabled with the `reportProgress` option.
Note: The optional `fetch` implementation of `HttpClient` does not report _upload_ progress events.
NOTE: The optional `fetch` implementation of `HttpClient` does not report _upload_ progress events.
To observe the event stream, set the `observe` option to `'events'`:
+1 -1
View File
@@ -2,7 +2,7 @@
`HttpClient` includes built-in support for two common HTTP security mechanisms: XSSI protection and XSRF/CSRF protection.
Tip: Also consider adopting a [Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy) for your APIs.
TIP: Also consider adopting a [Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy) for your APIs.
## XSSI protection
+4 -4
View File
@@ -66,7 +66,7 @@ expect(await configPromise).toEqual(DEFAULT_CONFIG);
httpTesting.verify();
</docs-code>
Note: `expectOne` will fail if the test has made more than one request which matches the given criteria.
NOTE: `expectOne` will fail if the test has made more than one request which matches the given criteria.
As an alternative to asserting on `req.method`, you could instead use an expanded form of `expectOne` to also match the request method:
@@ -181,7 +181,7 @@ const req = httpTesting.expectOne('/api/config');
expect(req.request.headers.get('X-Authentication-Token')).toEqual(service.getAuthToken());
</docs-code>
A similar interceptor could be implemented with class based interceptors:
A similar interceptor could be implemented with class based interceptors:
<docs-code language="ts">
@Injectable()
@@ -204,9 +204,9 @@ TestBed.configureTestingModule({
providers: [
AuthService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
provideHttpClientTesting(),
// We rely on the HTTP_INTERCEPTORS token to register the AuthInterceptor as an HttpInterceptor
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
],
});
</docs-code>
</docs-code>
+2 -2
View File
@@ -93,7 +93,7 @@ Event replay supports _native browser events_, for example `click`, `mouseover`,
---
This feature ensures a consistent user experience, preventing user actions performed before Hydration from being ignored. Note: if you have [incremental hydration](guide/incremental-hydration) enabled, event replay is automatically enabled under the hood.
This feature ensures a consistent user experience, preventing user actions performed before Hydration from being ignored. NOTE: if you have [incremental hydration](guide/incremental-hydration) enabled, event replay is automatically enabled under the hood.
## Constraints
@@ -123,7 +123,7 @@ As an example, here are some of the most common cases of this issue.
If you are uncertain about whether your HTML is valid, you can use a [syntax validator](https://validator.w3.org/) to check it.
Note: While the HTML standard does not require the `<tbody>` element inside tables, modern browsers automatically create a `<tbody>` element in tables that do not declare one. Because of this inconsistency, always explicitly declare a `<tbody>` element in tables to avoid hydration errors.
NOTE: While the HTML standard does not require the `<tbody>` element inside tables, modern browsers automatically create a `<tbody>` element in tables that do not declare one. Because of this inconsistency, always explicitly declare a `<tbody>` element in tables to avoid hydration errors.
### Preserve Whitespaces Configuration
+1 -1
View File
@@ -32,7 +32,7 @@ To mark the greeting for translation, add the `i18n` attribute to the `<h1>` tag
### using conditional statement with `i18n`
The following `<div>` tag will display translated text as part of `div` and `aria-label` based on toggle status
The following `<div>` tag will display translated text as part of `div` and `aria-label` based on toggle status
<docs-code-multifile>
<docs-code header="src/app/app.component.html" path="adev/src/content/examples/i18n/src/app/app.component.html" visibleRegion="i18n-conditional"/>
+17 -17
View File
@@ -19,7 +19,7 @@ In addition to optimizing the loading of the LCP image, `NgOptimizedImage` enfor
If you're using a background image in CSS, [start here](#how-to-migrate-your-background-image).
**Note: Although the `NgOptimizedImage` directive was made a stable feature in Angular version 15, it has been backported and is available as a stable feature in versions 13.4.0 and 14.3.0 as well.**
**NOTE: Although the `NgOptimizedImage` directive was made a stable feature in Angular version 15, it has been backported and is available as a stable feature in versions 13.4.0 and 14.3.0 as well.**
## Getting Started
@@ -90,7 +90,7 @@ For **responsive images** (images which you've styled to grow and shrink relativ
For **fixed size images**, the `width` and `height` attributes should reflect the desired rendered size of the image. The aspect ratio of these attributes should always match the intrinsic aspect ratio of the image.
Note: If you don't know the size of your images, consider using "fill mode" to inherit the size of the parent container, as described below.
NOTE: If you don't know the size of your images, consider using "fill mode" to inherit the size of the parent container, as described below.
</docs-step>
</docs-workflow>
@@ -162,10 +162,10 @@ You can also specify a placeholder using a base64 [data URL](https://developer.m
<docs-code language="angular-html">
<img
ngSrc="cat.jpg"
width="400"
height="200"
<img
ngSrc="cat.jpg"
width="400"
height="200"
placeholder="data:image/png;base64,iVBORw0K..."
/>
@@ -179,11 +179,11 @@ By default, NgOptimizedImage applies a CSS blur effect to image placeholders. To
<docs-code language="angular-html">
<img
ngSrc="cat.jpg"
width="400"
height="200"
placeholder
<img
ngSrc="cat.jpg"
width="400"
height="200"
placeholder
[placeholderConfig]="{blur: false}"
/>
@@ -235,7 +235,7 @@ Defining a [`srcset` attribute](https://developer.mozilla.org/docs/Web/API/HTMLI
If your image should be "fixed" in size (i.e. the same size across devices, except for [pixel density](https://web.dev/codelab-density-descriptors/)), there is no need to set a `sizes` attribute. A `srcset` can be generated automatically from the image's width and height attributes with no further input required.
Example srcset generated:
Example srcset generated:
```angular-html
<img ... srcset="image-400w.jpg 1x, image-800w.jpg 2x">
```
@@ -376,7 +376,7 @@ providers: [
A loader function for the `NgOptimizedImage` directive takes an object with the `ImageLoaderConfig` type (from `@angular/common`) as its argument and returns the absolute URL of the image asset. The `ImageLoaderConfig` object contains the `src` property, and optional `width` and `loaderParams` properties.
Note: even though the `width` property may not always be present, a custom loader must use it to support requesting images at various widths in order for `ngSrcset` to work properly.
NOTE: even though the `width` property may not always be present, a custom loader must use it to support requesting images at various widths in order for `ngSrcset` to work properly.
### The `loaderParams` Property
@@ -416,7 +416,7 @@ Note that in the above example, we've invented the 'roundedCorners' property nam
The NgOptimizedImage does not directly support the `background-image` css property, but it is designed to easily accommodate the use case of having an image as the background of another element.
For a step-by-step process for migration from `background-image` to `NgOptimizedImage`, see the [How to migrate your background image](#how-to-migrate-your-background-image) section above.
For a step-by-step process for migration from `background-image` to `NgOptimizedImage`, see the [How to migrate your background image](#how-to-migrate-your-background-image) section above.
### Why can't I use `src` with `NgOptimizedImage`?
@@ -446,7 +446,7 @@ For maintenance reasons, we don't currently plan to support additional built-in
### Can I use this with the `<picture>` tag
No, but this is on our roadmap, so stay tuned.
No, but this is on our roadmap, so stay tuned.
If you're waiting on this feature, please upvote the Github issue [here](https://github.com/angular/angular/issues/56594).
@@ -454,11 +454,11 @@ If you're waiting on this feature, please upvote the Github issue [here](https:/
1. Using the performance tab of the Chrome DevTools, click on the "start profiling and reload page" button on the top left. It looks like a page refresh icon.
2. This will trigger a profiling snapshot of your Angular application.
2. This will trigger a profiling snapshot of your Angular application.
3. Once the profiling result is available, select "LCP" in the timings section.
4. A summary entry should appear in the panel at the bottom. You can find the LCP element in the row for "related node". Clicking on it will reveal the element in the Elements panel.
4. A summary entry should appear in the panel at the bottom. You can find the LCP element in the row for "related node". Clicking on it will reveal the element in the Elements panel.
<img alt="LCP in the Chrome DevTools" src="assets/images/guide/image-optimization/devtools-lcp.png">
@@ -1,6 +1,6 @@
# Incremental Hydration
Tip: Incremental hydration is currently in [developer preview](/reference/releases#developer-preview).
TIP: Incremental hydration is currently in [developer preview](/reference/releases#developer-preview).
**Incremental hydration** is an advanced type of [hydration](guide/hydration) that can leave sections of your application dehydrated and _incrementally_ trigger hydration of those sections as they are needed.
@@ -149,7 +149,7 @@ condition becomes truthy.
}
```
Note: `hydrate when` conditions only trigger when they are the top-most dehydrated `@defer` block. The condition provided for the trigger is
NOTE: `hydrate when` conditions only trigger when they are the top-most dehydrated `@defer` block. The condition provided for the trigger is
specified in the parent component, which needs to exist before it can be triggered. If the parent block is dehydrated, that expression will not yet
be resolvable by Angular.
@@ -168,7 +168,7 @@ renders would load the `@defer` block dependencies on viewport.
}
```
Note: Using `hydrate never` prevents hydration of the entire nested subtree of a given `@defer` block. No other `hydrate` triggers fire for content nested underneath that block.
NOTE: Using `hydrate never` prevents hydration of the entire nested subtree of a given `@defer` block. No other `hydrate` triggers fire for content nested underneath that block.
## Hydrate triggers alongside regular triggers
+1 -1
View File
@@ -107,7 +107,7 @@ export class CustomMenuModule { }
## `NgModule` providers
Tip: See the [Dependency Injection guide](guide/di) for information on dependency injection and providers.
TIP: See the [Dependency Injection guide](guide/di) for information on dependency injection and providers.
An `NgModule` can specify `providers` for injected dependencies. These providers are available to:
* Any standalone component, directive, or pipe that imports the NgModule, and
+1 -1
View File
@@ -23,5 +23,5 @@ The following are commonly used built-in pipes for data formatting:
- [`AsyncPipe`](api/common/AsyncPipe): Subscribe and unsubscribe to an asynchronous source such as an observable.
- [`JsonPipe`](api/common/JsonPipe): Display a component object property to the screen as JSON for debugging.
Note: For a complete list of built-in pipes, see the [pipes API documentation](/api?type=pipe "Pipes API reference summary").
NOTE: For a complete list of built-in pipes, see the [pipes API documentation](/api?type=pipe "Pipes API reference summary").
To learn more about using pipes for internationalization (i18n) efforts, see [formatting data based on locale](guide/i18n/format-data-locale).
+1 -1
View File
@@ -251,7 +251,7 @@ Content-Security-Policy: trusted-types angular angular#bundler; require-trusted-
<docs-callout title="Community contributions">
To learn more about troubleshooting Trusted Type configurations, the following resource might be helpful:
To learn more about troubleshooting Trusted Type configurations, the following resource might be HELPFUL:
[Prevent DOM-based cross-site scripting vulnerabilities with Trusted Types](https://web.dev/trusted-types/#how-to-use-trusted-types)
+1 -1
View File
@@ -2,7 +2,7 @@
Angular Signals is a system that granularly tracks how and where your state is used throughout an application, allowing the framework to optimize rendering updates.
</docs-decorative-header>
Tip: Check out Angular's [Essentials](essentials/signals) before diving into this comprehensive guide.
TIP: Check out Angular's [Essentials](essentials/signals) before diving into this comprehensive guide.
## What are signals?
+2 -2
View File
@@ -24,7 +24,7 @@ To add SSR to an **existing** project, use the Angular CLI `ng add` command.
ng add @angular/ssr
```
Note: Interested in the latest SSR advancements in Angular? Take a look at the developer preview [hybrid rendering APIs](guide/hybrid-rendering).
NOTE: Interested in the latest SSR advancements in Angular? Take a look at the developer preview [hybrid rendering APIs](guide/hybrid-rendering).
These commands create and update application code to enable SSR and adds extra files to the project structure.
@@ -41,7 +41,7 @@ To verify that the application is server-side rendered, run it locally with `ng
## Configure server-side rendering
Note: In Angular v17 and later, `server.ts` is no longer used by `ng serve`. The dev server will use `main.server.ts` directly to perform server side rendering.
NOTE: In Angular v17 and later, `server.ts` is no longer used by `ng serve`. The dev server will use `main.server.ts` directly to perform server side rendering.
The `server.ts` file configures a Node.js Express server and Angular server-side rendering. `CommonEngine` is used to render an Angular application.
@@ -2,7 +2,7 @@
Angular templates support control flow blocks that let you conditionally show, hide, and repeat elements.
Note: This was previously accomplished with the *ngIf, *ngFor, and \*ngSwitch directives.
NOTE: This was previously accomplished with the *ngIf, *ngFor, and \*ngSwitch directives.
## Conditionally display content with `@if`, `@else-if` and `@else`
@@ -72,7 +72,7 @@ Angular expressions additionally also support the following non-standard operato
| Optional chaining\* | `someObj.someProp?.nestedProp` |
| Non-null assertion (TypeScript) | `someObj!.someProp` |
\*Note: Optional chaining behaves differently from the standard JavaScript version in that if the left side of Angular’s optional chaining operator is `null` or `undefined`, it returns `null` instead of `undefined`.
\*NOTE: Optional chaining behaves differently from the standard JavaScript version in that if the left side of Angular’s optional chaining operator is `null` or `undefined`, it returns `null` instead of `undefined`.
### Unsupported operators
+1 -1
View File
@@ -3,7 +3,7 @@ In Angular, a template is a chunk of HTML.
Use special syntax within a template to leverage many of Angular's features.
</docs-decorative-header>
Tip: Check out Angular's [Essentials](essentials/templates) before diving into this comprehensive guide.
TIP: Check out Angular's [Essentials](essentials/templates) before diving into this comprehensive guide.
Every Angular component has a **template** that defines the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) that the component renders onto the page. By using templates, Angular is able to automatically keep your page up-to-date as data changes.
+1 -1
View File
@@ -4,7 +4,7 @@
Pipes are a special operator in Angular template expressions that allows you to transform data declaratively in your template. Pipes let you declare a transformation function once and then use that transformation across multiple templates. Angular pipes use the vertical bar character (`|`), inspired by the [Unix pipe](<https://en.wikipedia.org/wiki/Pipeline_(Unix)>).
Note: Angular's pipe syntax deviates from standard JavaScript, which uses the vertical bar character for the [bitwise OR operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR). Angular template expressions do not support bitwise operators.
NOTE: Angular's pipe syntax deviates from standard JavaScript, which uses the vertical bar character for the [bitwise OR operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR). Angular template expressions do not support bitwise operators.
Here is an example using some built-in pipes that Angular provides:
@@ -2,7 +2,7 @@
## Before you start
Tip: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses.
TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses.
### When does adding support for a test environment make sense?
@@ -2,7 +2,7 @@
## Before you start
Tip: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses.
TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses.
### When does creating a test harness make sense?
@@ -2,7 +2,7 @@
## Before you start
Tip: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses.
TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses.
### CDK Installation
@@ -111,7 +111,7 @@ export class UserProfile {
}
```
Tip: Want to know more about Angular components? See the [In-depth Components guide](guide/components) for the full details.
TIP: Want to know more about Angular components? See the [In-depth Components guide](guide/components) for the full details.
## Next Step
@@ -20,7 +20,7 @@ firstName.set('Jaime');
// You can also use the `update` method to change the value
// based on the previous value.
firstName.update(name => name.toUpperCase());
firstName.update(name => name.toUpperCase());
```
Angular tracks where signals are read and when they're updated. The framework uses this information to do additional work, such as updating the DOM with new state. This ability to respond to changing signal values over time is known as *reactivity*.
@@ -36,7 +36,7 @@ const firstName = signal('Morgan');
const firstNameCapitalized = computed(() => firstName().toUpperCase());
console.log(firstNameCapitalized()); // MORGAN
```
```
A `computed` signal is read-only; it does not have a `set` or an `update` method. Instead, the value of the `computed` signal automatically changes when any of the signals it reads change:
@@ -68,7 +68,7 @@ export class UserProfile {
}
```
Tip: Want to know more about Angular Signals? See the [In-depth Signals guide](guide/signals) for the full details.
TIP: Want to know more about Angular Signals? See the [In-depth Signals guide](guide/signals) for the full details.
## Next Step
@@ -70,12 +70,12 @@ Angular lets you add event listeners to an element in your template with parenth
```angular-ts
@Component({
/*...*/
// Add an 'click' event handler that calls the `cancelSubscription` method.
// Add an 'click' event handler that calls the `cancelSubscription` method.
template: `<button (click)="cancelSubscription()">Cancel subscription</button>`,
})
export class UserProfile {
/* ... */
cancelSubscription() { /* Your event handling code goes here. */ }
}
```
@@ -85,12 +85,12 @@ If you need to pass the [event](https://developer.mozilla.org/docs/Web/API/Event
```angular-ts
@Component({
/*...*/
// Add an 'click' event handler that calls the `cancelSubscription` method.
// Add an 'click' event handler that calls the `cancelSubscription` method.
template: `<button (click)="cancelSubscription($event)">Cancel subscription</button>`,
})
export class UserProfile {
/* ... */
cancelSubscription(event: Event) { /* Your event handling code goes here. */ }
}
```
@@ -118,7 +118,7 @@ The `@if` block also supports an optional `@else` block:
<!-- ... -->
} @else {
<h2>User settings</h2>
<!-- ... -->
<!-- ... -->
}
```
@@ -136,7 +136,7 @@ You can repeat part of a template multiple times with Angular's `@for` block:
Angular's uses the `track` keyword, shown in the example above, to associate data with the DOM elements created by `@for`. See [_Why is track in @for blocks important?_](guide/templates/control-flow#why-is-track-in-for-blocks-important) for more info.
Tip: Want to know more about Angular templates? See the [In-depth Templates guide](guide/templates) for the full details.
TIP: Want to know more about Angular templates? See the [In-depth Templates guide](guide/templates) for the full details.
## Next Step
+5 -5
View File
@@ -101,15 +101,15 @@ Alerts are just special paragraphs. They are helpful to call out (not to be conf
Style alerts starting on a new line in Markdown using the format `SEVERITY_LEVEL` + `:` + `ALERT_TEXT`.
Note: Use Note for ancillary/additional information that's not _essential_ to the main text.
NOTE: Use Note for ancillary/additional information that's not _essential_ to the main text.
Tip: Use Tip to call out a specific task/action users can perform, or a fact that plays directly into a task/action.
TIP: Use Tip to call out a specific task/action users can perform, or a fact that plays directly into a task/action.
TODO: Use TODO for incomplete documentation that you plan to expand soon. You can also assign the TODO, e.g. TODO(emmatwersky): Text.
QUESTION: Use Question to pose a question to the reader, kind of like a mini-quiz that they should be able to answer.
Summary: Use Summary to provide a two- or three-sentence synopsis of the page or section content, so readers can figure out whether this is the right place for them.
SUMMARY: Use Summary to provide a two- or three-sentence synopsis of the page or section content, so readers can figure out whether this is the right place for them.
TLDR: Use TL;DR (or TLDR) if you can provide the essential information about a page or section in a sentence or two. For example, TLDR: Rhubarb is a cat.
@@ -119,7 +119,7 @@ IMPORTANT: Use Important for information that's crucial to comprehending the tex
HELPFUL: Use Best practice to call out practices that are known to be successful or better than alternatives.
Note: Heads up `developers`! Alerts _can_ have a [link](#alerts) and other nested styles (but try to **use this sparingly**)!.
NOTE: Heads up `developers`! Alerts _can_ have a [link](#alerts) and other nested styles (but try to **use this sparingly**)!.
## Code
@@ -209,7 +209,7 @@ You can create multifile examples by wrapping the examples inside a `<docs-code-
Adding the `preview` flag builds a running example of the code below the code snippet. This also automatically adds a button to open the running example in Stackblitz.
Note: `preview` only works with standalone.
NOTE: `preview` only works with standalone.
#### built-in-template-functions
+2 -2
View File
@@ -12,7 +12,7 @@ export class Car {
// OK: field initializer
spareTyre = inject(Tyre);
constructor() {
// OK: constructor body
this.radio = inject(Radio);
@@ -51,7 +51,7 @@ Work backwards from the stack trace of the error to identify a place where the d
To fix the error move the [`inject`](api/core/inject) call to an allowed place (usually a class constructor or a field initializer).
**Note:** If you are running in a test context, `TestBed.runInInjectionContext` will enable `inject()` to succeed.
**NOTE:** If you are running in a test context, `TestBed.runInInjectionContext` will enable `inject()` to succeed.
```typescript
TestBed.runInInjectionContext(() => {
+1 -1
View File
@@ -5,7 +5,7 @@ Hot Module Replacement (HMR) is a technique used by development servers to avoid
When the HMR is enabled in Angular, all `@defer` block dependencies are loaded
eagerly, instead of waiting for configured trigger conditions (both for client-only and incremental hydration triggers). This is needed
for the HMR to function properly, replacing components in an application at runtime
without the need to reload the entire page. Note: the actual rendering of defer
without the need to reload the entire page. NOTE: the actual rendering of defer
blocks respects trigger conditions in the HMR mode.
If you want to test `@defer` block behavior in development mode and ensure that
@@ -103,7 +103,7 @@ fixed in `inject()` which can cause new compilation errors to show up. If you en
the migration will produce a non-null assertion after the `inject()` call to match the old type,
at the expense of potentially hiding type errors.
**Note:** non-null assertions won't be added to parameters that are already typed to be nullable,
**NOTE:** non-null assertions won't be added to parameters that are already typed to be nullable,
because the code that depends on them likely already accounts for their nullability.
#### Before
@@ -33,7 +33,7 @@ Before using the schematic, please ensure that the project:
The migration process is composed of three steps. You'll have to run it multiple times and check manually that the project builds and behaves as expected.
Note: While the schematic can automatically update most code, some edge cases require developer intervention.
NOTE: While the schematic can automatically update most code, some edge cases require developer intervention.
You should plan to apply manual fixes after each step of the migration. Additionally, the new code generated by the schematic may not match your code's formatting rules.
Run the migration in the order listed below, verifying that your code builds and runs between each step:
@@ -478,4 +478,4 @@ HELPFUL: *The compiler expected a reference to a symbol at the location specifie
This error can occur if you use an expression in the `extends` clause of a class.
<!--todo: Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](https://github.com/angular/angular/pull/17712#discussion_r132025495). -->
<!--todo: Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](https://github.com/angular/angular/pull/17712#discussion_r132025495). -->
@@ -533,4 +533,4 @@ IMPORTANT: Avoiding the use of modules with non-local side effects (outside of p
Report issues and feature requests on [GitHub](https://github.com/angular/angular-cli/issues).
Please provide a minimal reproduction where possible to aid the team in addressing issues.
Please provide a minimal reproduction where possible to aid the team in addressing issues.
+2 -2
View File
@@ -173,7 +173,7 @@ Later, import the file in the initial view of the profiler by clicking the **Cho
## Inspect your injectors
Note: The Injector Tree is available for Angular Applications built with version 17 or higher.
NOTE: The Injector Tree is available for Angular Applications built with version 17 or higher.
### View the injector hierarchy of your application
@@ -185,7 +185,7 @@ Later, import the file in the initial view of the profiler by clicking the **Cho
When a specific injector is selected, the path that Angular's dependency injection algorithm traverses from that injector to the root is highlighted. For element injectors, this includes highlighting the environment injectors that the dependency injection algorithm jumps to when a dependency cannot be resolved in the element hierarchy.
See [resolution rules](guide/di/hierarchical-dependency-injection#resolution-rules) for more details about how Angular resolves resolution paths.
See [resolution rules](guide/di/hierarchical-dependency-injection#resolution-rules) for more details about how Angular resolves resolution paths.
<img src="assets/images/guide/devtools/di-injector-tree-selected.png" alt="A screenshot of the 'Profiler' tab displaying how the injector tree visualize highlights resolution paths when an injector is selected.">
@@ -82,7 +82,7 @@ Update `app.component.ts` to include a `@loading` block with a minimum parameter
}
</docs-code>
Note: this example uses two parameters, separated by the ; character.
NOTE: this example uses two parameters, separated by the ; character.
</docs-step>
@@ -73,7 +73,7 @@ Next, update the template to include a button with the label "Show all comments"
}
</docs-code>
Note: for more information on [template variables check the documentation](https://angular.dev/guide/templates/reference-variables#).
NOTE: for more information on [template variables check the documentation](https://angular.dev/guide/templates/reference-variables#).
</docs-step>
@@ -25,7 +25,7 @@ The lessons in this tutorial assume that you have experience with the following:
These lessons can be completed using a local installation of the Angular tools or in our embedded editor. Local Angular development can be completed on Windows, MacOS or Linux based systems.
Note: Look for alerts like this one, which call out steps that may only be for your local editor.
NOTE: Look for alerts like this one, which call out steps that may only be for your local editor.
## Conceptual preview of your first Angular app
@@ -36,7 +36,7 @@ This app uses features that are common to many Angular apps.
## Local development environment
Note: This step is only for your local environment!
NOTE: This step is only for your local environment!
Perform these steps in a command-line tool on the computer you want to use for this tutorial.
@@ -8,7 +8,7 @@ This first lesson serves as the starting point from which each lesson in this tu
The updated app you have after this lesson confirms that you and your IDE are ready to begin creating an Angular app.
Note: If you are working with the embedded editor, skip to [step three](#create-%60hello-world%60).
NOTE: If you are working with the embedded editor, skip to [step three](#create-%60hello-world%60).
When working in the browser playground, you do not need to `ng serve` to run the app. Other commands like `ng generate` can be done in the console window to your right.
<docs-workflow>
@@ -83,7 +83,7 @@ In this step, you update the Angular project files to change the displayed conte
In your IDE:
1. Open `first-app/src/index.html`.
Note: This step and the next are only for your local environment!
NOTE: This step and the next are only for your local environment!
1. In `index.html`, replace the `<title>` element with this code to update the title of the app.
@@ -109,7 +109,7 @@ In your IDE:
</docs-workflow>
Summary: In this lesson, you updated a default Angular app to display *Hello world*.
SUMMARY: In this lesson, you updated a default Angular app to display *Hello world*.
In the process, you learned about the `ng serve` command to serve your app locally for testing.
For more information about the topics covered in this lesson, visit:
@@ -43,7 +43,7 @@ In the **Terminal** pane of your IDE:
1. Run this command to build and serve your app.
Note: This step is only for your local environment!
NOTE: This step is only for your local environment!
<docs-code language="shell">
ng serve
@@ -104,7 +104,7 @@ In the **Edit** pane of your IDE:
1. Next, open `home.component.css` in the editor and update the content with these styles.
Note: In the browser, these can go in `src/app/home/home.component.ts` in the `styles` array.
NOTE: In the browser, these can go in `src/app/home/home.component.ts` in the `styles` array.
<docs-code header="Replace in src/app/home/home.component.css" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/home/home.component.css"/>
@@ -117,7 +117,7 @@ In the **Edit** pane of your IDE:
</docs-workflow>
Summary: In this lesson, you created a new component for your app and gave it a filter edit control and button.
SUMMARY: In this lesson, you created a new component for your app and gave it a filter edit control and button.
For more information about the topics covered in this lesson, visit:
@@ -29,7 +29,7 @@ In the **Terminal** pane of your IDE:
ng serve
</docs-code>
Note: This step is only for your local environment!
NOTE: This step is only for your local environment!
1. Open a browser and navigate to `http://localhost:4200` to find the application.
1. Confirm that the app builds without error.
@@ -64,7 +64,7 @@ In this step, you will copy over the pre-written styles for the `HousingLocation
1. Open `src/app/housing-location/housing-location.component.css`, and paste the styles below into the file:
Note: In the browser, these can go in `src/app/housing-location/housing-location.component.ts` in the `styles` array.
NOTE: In the browser, these can go in `src/app/housing-location/housing-location.component.ts` in the `styles` array.
<docs-code header="Add CSS styles to housing location to the component in src/app/housing-location/housing-location.component.css" path="adev/src/content/tutorials/first-app/steps/04-interfaces/src/app/housing-location/housing-location.component.css"/>
@@ -76,4 +76,4 @@ In this step, you will copy over the pre-written styles for the `HousingLocation
</docs-workflow>
Summary: In this lesson, you created a new component for your app and added it to the app's layout.
SUMMARY: In this lesson, you created a new component for your app and added it to the app's layout.
@@ -87,7 +87,7 @@ There are a few more lessons to complete before that happens.
</docs-workflow>
Summary: In this lesson, you created an interface that created a new data type for your app.
SUMMARY: In this lesson, you created an interface that created a new data type for your app.
This new data type makes it possible for you to specify where `HousingLocation` data is required.
This new data type also makes it possible for your IDE and the TypeScript compiler can ensure that `HousingLocation` data is used where it's required.
@@ -44,7 +44,7 @@ In the code editor:
</docs-workflow>
Summary: In this lesson, you created a new property decorated with the `@Input()` decorator. You also used the non-null assertion operator to notify the compiler that the value of the new property won't be `null` or `undefined`.
SUMMARY: In this lesson, you created a new property decorated with the `@Input()` decorator. You also used the non-null assertion operator to notify the compiler that the value of the new property won't be `null` or `undefined`.
<docs-pill-row>
<docs-pill href="guide/components/inputs" title="Accepting data with input properties"/>
@@ -40,7 +40,7 @@ In the code editor:
</docs-workflow>
Summary: In this lesson, you added a new property binding and passed in a reference to a class property. Now, the `HousingLocationComponent` has access to data that it can use to customize the component's display.
SUMMARY: In this lesson, you added a new property binding and passed in a reference to a class property. Now, the `HousingLocationComponent` has access to data that it can use to customize the component's display.
For more information about the topics covered in this lesson, visit:
@@ -43,7 +43,7 @@ In the code editor:
</docs-workflow>
Summary: In this lesson, you added a new HTML structure and used Angular template syntax to render values in the `HousingLocation` template.
SUMMARY: In this lesson, you added a new HTML structure and used Angular template syntax to render values in the `HousingLocation` template.
Now, you have two important skills:
@@ -53,7 +53,7 @@ Now the app has a dataset that you can use to display the entries in the browser
</docs-workflow>
Summary: In this lesson, you used the `ngFor` directive to repeat data dynamically in Angular templates. You also added a new array of data to be used in the Angular app. The application now dynamically renders a list of housing locations in the browser.
SUMMARY: In this lesson, you used the `ngFor` directive to repeat data dynamically in Angular templates. You also added a new array of data to be used in the Angular app. The application now dynamically renders a list of housing locations in the browser.
The app is taking shape, great job.
@@ -95,7 +95,7 @@ In the **Edit** pane of your IDE, in `src/app/home/home.component.ts`:
</docs-workflow>
Summary: In this lesson, you added an Angular service to your app and injected it into the `HomeComponent` class.
SUMMARY: In this lesson, you added an Angular service to your app and injected it into the `HomeComponent` class.
This compartmentalizes how your app gets its data.
For now, the new service gets its data from a static array of data.
In a later lesson, you'll refactor the service to get its data from an API endpoint.
@@ -75,7 +75,7 @@ In the previous step you removed the reference to the `<app-home>` component in
</docs-workflow>
Summary: In this lesson, you enabled routing in your app as well as defined new routes. Now your app can support navigation between views. In the next lesson, you will learn to navigate to the "details" page for a given housing location.
SUMMARY: In this lesson, you enabled routing in your app as well as defined new routes. Now your app can support navigation between views. In the next lesson, you will learn to navigate to the "details" page for a given housing location.
You are making great progress with your app, well done.
@@ -113,7 +113,7 @@ In a previous lesson you updated the `AppComponent` template to include a `route
</docs-workflow>
Summary: In this lesson you added routing to show details pages.
SUMMARY: In this lesson you added routing to show details pages.
You now know how to:
@@ -96,7 +96,7 @@ This step tests the new form to see that when the form data is submitted to the
</docs-workflow>
Summary: In this lesson, you updated your app to add a form using Angular's forms feature, and connect the data captured in the form to a component using an event handler.
SUMMARY: In this lesson, you updated your app to add a form using Angular's forms feature, and connect the data captured in the form to a component using an event handler.
For more information about the topics covered in this lesson, visit:
@@ -75,7 +75,7 @@ The template has been updated to bind the `filterResults` function to the `click
</docs-workflow>
Summary: In this lesson, you updated your app to use template variables to interact with template values, and add search functionality using event binding and array functions.
SUMMARY: In this lesson, you updated your app to use template variables to interact with template values, and add search functionality using event binding and array functions.
For more information about the topics covered in this lesson, visit:
@@ -196,9 +196,9 @@ The server is now reading data from the HTTP request but the components that rel
</docs-workflow>
Note: This lesson relies on the `fetch` browser API. For the support of interceptors, please refer to the [Http Client documentation](/guide/http)
NOTE: This lesson relies on the `fetch` browser API. For the support of interceptors, please refer to the [Http Client documentation](/guide/http)
Summary: In this lesson, you updated your app to use a local web server (`json-server`), and use asynchronous service methods to retrieve data.
SUMMARY: In this lesson, you updated your app to use a local web server (`json-server`), and use asynchronous service methods to retrieve data.
Congratulations! You've successfully completed this tutorial and are ready to continue your journey with building even more complex Angular Apps.
@@ -61,7 +61,7 @@ In situations where you can't or don't want to specify a static `height` and `wi
</div>
```
Note: For the `fill` image to render properly, its parent element must be styled with `position: "relative"`, `position: "fixed"`, or `position: "absolute"`.
NOTE: For the `fill` image to render properly, its parent element must be styled with `position: "relative"`, `position: "fixed"`, or `position: "absolute"`.
</docs-step>
@@ -57,7 +57,7 @@ Update the input to use the `ngModel` directive, specifically with the following
After you've made changes, try entering a value in the input field. Notice how it updates on the screen (yes, very cool).
Note: The syntax `[()]` is known as "banana in a box" but it represents two-way binding: property binding and event binding. Learn more in the [Angular docs about two-way data binding](guide/templates/two-way-binding).
NOTE: The syntax `[()]` is known as "banana in a box" but it represents two-way binding: property binding and event binding. Learn more in the [Angular docs about two-way data binding](guide/templates/two-way-binding).
</docs-step>
@@ -36,7 +36,7 @@ The values in the object passed to the decorator are considered to be the config
<br>
Update the `@Injectable` decorator in `car.service.ts` to include the configuration for `providedIn: 'root'`.
Tip: Use the above example to find the correct syntax.
TIP: Use the above example to find the correct syntax.
</docs-step>
@@ -2,7 +2,7 @@
Creating an injectable service is the first part of the dependency injection (DI) system in Angular. How do you inject a service into a component? Angular has a convenient function called `inject()` that can be used in the proper context.
Note: Injection contexts are beyond the scope of this tutorial, but you can find more information in the [Angular Docs](guide/di/dependency-injection-context) if you would like to learn more.
NOTE: Injection contexts are beyond the scope of this tutorial, but you can find more information in the [Angular Docs](guide/di/dependency-injection-context) if you would like to learn more.
In this activity, you'll learn how to inject a service and use it in a component.
@@ -23,7 +23,7 @@ class PetCareDashboardComponent {
In `app.component.ts`, using the `inject()` function inject the `CarService` and assign it to a property called `carService`
Note: Notice the difference between the property `carService` and the class `CarService`.
NOTE: Notice the difference between the property `carService` and the class `CarService`.
</docs-step>
@@ -33,7 +33,7 @@ Alright, now you give this a try:
In `app.component.ts`, update the constructor code to match the code below:
Tip: Remember, if you get stuck refer to the example on this activity page.
TIP: Remember, if you get stuck refer to the example on this activity page.
```ts
constructor(private carService: CarService) {
@@ -29,7 +29,7 @@ template: `
`
</docs-code>
Note: What's that format? The parameter for the `DecimalPipe` is called `digitsInfo`, this parameter uses the format: `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`
NOTE: What's that format? The parameter for the `DecimalPipe` is called `digitsInfo`, this parameter uses the format: `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`
</docs-step>
@@ -48,7 +48,7 @@ Update the template to display each user name in a `p` element using the `@for`
}
```
Note: the use of `track` is required, you may use the `id` or some other unique identifier.
NOTE: the use of `track` is required, you may use the `id` or some other unique identifier.
</docs-step>