From f8a944314cfe141dbd60f4fa7e39d769ac524ff6 Mon Sep 17 00:00:00 2001 From: Matthieu Riegler Date: Mon, 26 May 2025 22:03:15 +0200 Subject: [PATCH] docs: remove unnecessary mention of ngIf/ngFor from llms-full (#61694) PR Close #61694 --- .../guide/directives/structural-directives.md | 9 +- adev/src/content/guide/forms/dynamic-forms.md | 2 +- .../content/guide/forms/form-validation.md | 5 +- .../src/content/guide/forms/reactive-forms.md | 2 +- .../content/guide/templates/control-flow.md | 2 - adev/src/content/guide/templates/variables.md | 11 - .../guide/testing/components-scenarios.md | 2 +- .../testing/creating-component-harnesses.md | 2 +- .../src/content/guide/testing/utility-apis.md | 2 +- adev/src/llms-full.txt | 188 +++++++++--------- 10 files changed, 102 insertions(+), 123 deletions(-) diff --git a/adev/src/content/guide/directives/structural-directives.md b/adev/src/content/guide/directives/structural-directives.md index 5c4024ddedb..2a6e6e09c42 100644 --- a/adev/src/content/guide/directives/structural-directives.md +++ b/adev/src/content/guide/directives/structural-directives.md @@ -166,10 +166,11 @@ The following table provides shorthand examples: | Shorthand | How Angular interprets the syntax | |:--- |:--- | -| `*ngFor="let item of [1,2,3]"` | `` | -| `*ngFor="let item of [1,2,3] as items; trackBy: myTrack; index as i"` | `` | -| `*ngIf="exp"`| `` | -| `*ngIf="exp as value"` | `` | +| `*myDir="let item of [1,2,3]"` | `` | +| `*myDir="let item of [1,2,3] as items; trackBy: myTrack; index as i"` | `` | +| `*ngComponentOutlet="componentClass";` | `` | +| `*ngComponentOutlet="componentClass; inputs: myInputs";` | `` | +| `*myDir="exp as value"` | `` | ## Improving template type checking for custom directives diff --git a/adev/src/content/guide/forms/dynamic-forms.md b/adev/src/content/guide/forms/dynamic-forms.md index 8beb67548f5..bab82a48efa 100644 --- a/adev/src/content/guide/forms/dynamic-forms.md +++ b/adev/src/content/guide/forms/dynamic-forms.md @@ -86,7 +86,7 @@ The `DynamicFormQuestionComponent` creates form groups and populates them with c The goal of the `DynamicFormQuestionComponent` is to present question types defined in your model. You only have two types of questions at this point but you can imagine many more. -The `ngSwitch` statement in the template determines which type of question to display. +The `@switch` block in the template determines which type of question to display. The switch uses directives with the [`formControlName`](api/forms/FormControlName "FormControlName directive API reference") and [`formGroup`](api/forms/FormGroupDirective "FormGroupDirective API reference") selectors. Both directives are defined in `ReactiveFormsModule`. diff --git a/adev/src/content/guide/forms/form-validation.md b/adev/src/content/guide/forms/form-validation.md index e36fcee4af6..014599ea9d9 100644 --- a/adev/src/content/guide/forms/form-validation.md +++ b/adev/src/content/guide/forms/form-validation.md @@ -254,8 +254,9 @@ The following example shows how to achieve this in a template-driven form. - - +@if(model.pending) { + +} ### Implementing a custom async validator diff --git a/adev/src/content/guide/forms/reactive-forms.md b/adev/src/content/guide/forms/reactive-forms.md index 9ece85841ad..d1fd267e928 100644 --- a/adev/src/content/guide/forms/reactive-forms.md +++ b/adev/src/content/guide/forms/reactive-forms.md @@ -375,7 +375,7 @@ Add the following template HTML after the `
` closing the `formGroupName` el -The `*ngFor` directive iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input. +The `@for` block iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input. Each time a new alias instance is added, the new form array instance is provided its control based on the index. This lets you track each individual control when calculating the status and value of the root control. diff --git a/adev/src/content/guide/templates/control-flow.md b/adev/src/content/guide/templates/control-flow.md index 29087ee2aa0..c3196b5cedd 100644 --- a/adev/src/content/guide/templates/control-flow.md +++ b/adev/src/content/guide/templates/control-flow.md @@ -2,8 +2,6 @@ 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. - ## Conditionally display content with `@if`, `@else-if` and `@else` The `@if` block conditionally displays its content when its condition expression is truthy: diff --git a/adev/src/content/guide/templates/variables.md b/adev/src/content/guide/templates/variables.md index f8a40ee4a0d..9b3ce1e4aed 100644 --- a/adev/src/content/guide/templates/variables.md +++ b/adev/src/content/guide/templates/variables.md @@ -81,18 +81,7 @@ Since `@let` declarations are not hoisted, they **cannot** be accessed by parent } } -
- {{topLevel + insideDiv}} - - @let nestedNgIf = value; - -
- {{topLevel + insideDiv + nestedNgIf}} -
-
- {{nested}} -{{nestedNgIf}} ``` ### Full syntax diff --git a/adev/src/content/guide/testing/components-scenarios.md b/adev/src/content/guide/testing/components-scenarios.md index e9c5383e091..de855e8afc5 100644 --- a/adev/src/content/guide/testing/components-scenarios.md +++ b/adev/src/content/guide/testing/components-scenarios.md @@ -425,7 +425,7 @@ The `DashboardHeroComponent` is embedded in the `DashboardComponent` template li -The `DashboardHeroComponent` appears in an `*ngFor` repeater, which sets each component's `hero` input property to the looping value and listens for the component's `selected` event. +The `DashboardHeroComponent` appears in an `@for` block, which sets each component's `hero` input property to the looping value and listens for the component's `selected` event. Here's the component's full definition: diff --git a/adev/src/content/guide/testing/creating-component-harnesses.md b/adev/src/content/guide/testing/creating-component-harnesses.md index a3b5ffcbbeb..4e82cac9a68 100644 --- a/adev/src/content/guide/testing/creating-component-harnesses.md +++ b/adev/src/content/guide/testing/creating-component-harnesses.md @@ -59,7 +59,7 @@ While `ComponentHarness` subclasses require only the `hostSelector` property, mo Each instance of a `ComponentHarness` subclass represents a particular instance of the corresponding component. You can access the component's host element via the `host() `method from the `ComponentHarness` base class. -`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `ngIf` hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. +`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `@if` block hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. See the [ComponentHarness API reference page](/api/cdk/testing/ComponentHarness) for the full list details of the different `locatorFor` methods. diff --git a/adev/src/content/guide/testing/utility-apis.md b/adev/src/content/guide/testing/utility-apis.md index a76e4a98513..dd218d7d351 100644 --- a/adev/src/content/guide/testing/utility-apis.md +++ b/adev/src/content/guide/testing/utility-apis.md @@ -123,7 +123,7 @@ Here are the most useful `DebugElement` members for testers, in approximate orde | `queryAll` | Calling `queryAll(predicate: Predicate)` returns all `DebugElements` that matches the [predicate](#query-predicate) at any depth in subtree. | | `injector` | The host dependency injector. For example, the root element's component instance injector. | | `componentInstance` | The element's own component instance, if it has one. | -| `context` | An object that provides parent context for this element. Often an ancestor component instance that governs this element.
When an element is repeated within `*ngFor`, the context is an `NgForOf` whose `$implicit` property is the value of the row instance value. For example, the `hero` in `*ngFor="let hero of heroes"`. | +| `context` | An object that provides parent context for this element. Often an ancestor component instance that governs this element.
When an element is repeated within `@for` block, the context is an `RepeaterContext` whose `$implicit` property is the value of the row instance value. For example, the `hero` in `@for(hero of heroes; ...)`. | | `children` | The immediate `DebugElement` children. Walk the tree by descending through `children`. `DebugElement` also has `childNodes`, a list of `DebugNode` objects. `DebugElement` derives from `DebugNode` objects and there are often more nodes than elements. Testers can usually ignore plain nodes. | | `parent` | The `DebugElement` parent. Null if this is the root element. | | `name` | The element tag name, if it is an element. | diff --git a/adev/src/llms-full.txt b/adev/src/llms-full.txt index e23fd4ef3ee..5d532130b7e 100644 --- a/adev/src/llms-full.txt +++ b/adev/src/llms-full.txt @@ -2392,8 +2392,6 @@ If an element has multiple bindings for the same style property, Angular resolve 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. - ## Conditionally display content with `@if`, `@else-if` and `@else` The `@if` block conditionally displays its content when its condition expression is truthy: @@ -2600,18 +2598,7 @@ Since `@let` declarations are not hoisted, they **cannot** be accessed by parent } } -
- {{topLevel + insideDiv}} - - @let nestedNgIf = value; - -
- {{topLevel + insideDiv + nestedNgIf}} -
-
- {{nested}} -{{nestedNgIf}} ``` ### Full syntax @@ -3135,7 +3122,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 @@ -3491,10 +3478,11 @@ The following table provides shorthand examples: | Shorthand | How Angular interprets the syntax | |:--- |:--- | -| `*ngFor="let item of [1,2,3]"` | `` | -| `*ngFor="let item of [1,2,3] as items; trackBy: myTrack; index as i"` | `` | -| `*ngIf="exp"`| `` | -| `*ngIf="exp as value"` | `` | +| `*myDir="let item of [1,2,3]"` | `` | +| `*myDir="let item of [1,2,3] as items; trackBy: myTrack; index as i"` | `` | +| `*ngComponentOutlet="componentClass";` | `` | +| `*ngComponentOutlet="componentClass; inputs: myInputs";` | `` | +| `*myDir="exp as value"` | `` | ## Improving template type checking for custom directives @@ -6284,8 +6272,6 @@ You should maintain the relationship between the component and its token while s The recommended style is to use the component base name with the suffix "`Token`" to name your lightweight injection tokens: "`LibHeaderToken`." # RxJS interop with Angular signals -IMPORTANT: The RxJS Interop package is available for [developer preview](reference/releases#developer-preview). It's ready for you to try, but it might change before it is stable. - The `@angular/rxjs-interop` package offers APIs that help you integrate RxJS and Angular signals. ## Create a signal from an RxJs Observable with `toSignal` @@ -7544,7 +7530,7 @@ Add the following template HTML after the `
` closing the `formGroupName` el -The `*ngFor` directive iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input. +The `@for` block iterates over each form control instance provided by the aliases form array instance. Because form array elements are unnamed, you assign the index to the `i` variable and pass it to each control to bind it to the `formControlName` input. Each time a new alias instance is added, the new form array instance is provided its control based on the index. This lets you track each individual control when calculating the status and value of the root control. @@ -8405,7 +8391,9 @@ The following example shows how to achieve this in a template-driven form. - +@if(model.pending) { + +} ``` ### Implementing a custom async validator @@ -8416,7 +8404,7 @@ To validate the potential role entry, the validator must initiate an asynchronou The following code creates the validator class, `UniqueRoleValidator`, which implements the `AsyncValidator` interface. ``` -The `actorsService` property is initialized with an instace of the `ActorsService` token, which defines the following interface. +The `actorsService` property is initialized with an instance of the `ActorsService` token, which defines the following interface. interface ActorsService { @@ -8565,7 +8553,7 @@ The form relies on a [`[formGroup]` directive](api/forms/FormGroupDirective "API The `DynamicFormQuestionComponent` creates form groups and populates them with controls defined in the question model, specifying display and validation rules. The goal of the `DynamicFormQuestionComponent` is to present question types defined in your model. You only have two types of questions at this point but you can imagine many more. -The `ngSwitch` statement in the template determines which type of question to display. +The `@switch` block in the template determines which type of question to display. The switch uses directives with the [`formControlName`](api/forms/FormControlName "FormControlName directive API reference") and [`formGroup`](api/forms/FormGroupDirective "FormGroupDirective API reference") selectors. Both directives are defined in `ReactiveFormsModule`. @@ -9184,26 +9172,27 @@ To learn more about the Angular Router, see the following topics: HELPFUL: This content is based on [Custom Route Matching with the Angular Router](https://medium.com/@brandontroberts/custom-route-matching-with-the-angular-router-fbdd48665483), by [Brandon Roberts](https://twitter.com/brandontroberts). # Server and hybrid rendering +Angular ships all applications as client-side rendered (CSR) by default. While this approach delivers a initial payload that's lightweight, it introduces trade-offs including slower load times, degraded performance metrics, and higher resource demands since the user's device performs most of the computations. As a result, many applications achieve significant performance improvements by integrating server-side rendering (SSR) into a hybrid rendering strategy. + ## What is hybrid rendering? -Hybrid rendering combines the benefits of server-side rendering (SSR), pre-rendering (also known as "static site generation" or SSG) and client-side rendering (CSR) to optimize your Angular application. It allows you to render different parts of your application using different strategies, giving you fine-grained control over how your app is delivered to users. +Hybrid rendering allows developers to leverage the benefits of server-side rendering (SSR), pre-rendering (also known as "static site generation" or SSG) and client-side rendering (CSR) to optimize your Angular application. It gives you fine-grained control over how your different parts of your app is rendered to give your users the best experience possible. ## Setting up hybrid rendering -You can create a **new** project with server-side rendering with the Angular CLI: +You can create a **new** project with hybrid rendering by using the server-side rendering flag (i.e., `--ssr`) with the Angular CLI `ng new` command: ```shell ng new --ssr ``` -You can also add server-side rendering to an existing project with the `ng add` command: +You can also enable hybrid rendering by adding server-side rendering to an existing project with the `ng add` command: ```shell ng add @angular/ssr ``` -NOTE: By default, Angular prerenders your entire application and generates a server file. To disable this and create a fully static app, set `outputMode` to `static`. To enable SSR, update the server routes to use `RenderMode.Server`. -For more details, see [`Server routing`](#server-routing) and [`Generate a fully static application`](#generate-a-fully-static-application). +NOTE: By default, Angular prerenders your entire application and generates a server file. To disable this and create a fully static app, set `outputMode` to `static`. To enable SSR, update the server routes to use `RenderMode.Server`. For more details, see [`Server routing`](#server-routing) and [`Generate a fully static application`](#generate-a-fully-static-application). ## Server routing @@ -9425,6 +9414,31 @@ export const serverRoutes: ServerRoute[] = [ ]; ``` +## Authoring server-compatible components + +Some common browser APIs and capabilities might not be available on the server. Applications cannot make use of browser-specific global objects like `window`, `document`, `navigator`, or `location` as well as certain properties of `HTMLElement`. + +In general, code which relies on browser-specific symbols should only be executed in the browser, not on the server. This can be enforced through the [`afterEveryRender`](api/core/afterEveryRender) and [`afterNextRender`](api/core/afterNextRender) lifecycle hooks. These are only executed on the browser and skipped on the server. + +```typescript +import { Component, ViewChild, afterNextRender } from '@angular/core'; + +@Component({ + selector: 'my-cmp', + template: `{{ ... }}`, +}) +export class MyComponent { + @ViewChild('content') contentRef: ElementRef; + + constructor() { + afterNextRender(() => { + // Safe to check `scrollHeight` because this will only run in the browser, not the server. + console.log('content height: ' + this.contentRef.nativeElement.scrollHeight); + }); + } +} +``` + ## Accessing Request and Response via DI The `@angular/core` package provides several tokens for interacting with the server-side rendering environment. These tokens give you access to crucial information and objects within your Angular application during SSR. @@ -9449,11 +9463,52 @@ export class MyComponent { ``` IMPORTANT: The above tokens will be `null` in the following scenarios: + - During the build processes. - When the application is rendered in the browser (CSR). - When performing static site generation (SSG). - During route extraction in development (at the time of the request). +## Generate a fully static application + +By default, Angular prerenders your entire application and generates a server file for handling requests. This allows your app to serve pre-rendered content to users. However, if you prefer a fully static site without a server, you can opt out of this behavior by setting the `outputMode` to `static` in your `angular.json` configuration file. + +When `outputMode` is set to `static`, Angular generates pre-rendered HTML files for each route at build time, but it does not generate a server file or require a Node.js server to serve the app. This is useful for deploying to static hosting providers where a backend server is not needed. + +To configure this, update your `angular.json` file as follows: + +```json +{ + "projects": { + "your-app": { + "architect": { + "build": { + "options": { + "outputMode": "static" + } + } + } + } + } +} +``` + +## Caching data when using HttpClient + +[`HttpClient`](api/common/http/HttpClient) cached outgoing network requests when running on the server. This information is serialized and transferred to the browser as part of the initial HTML sent from the server. In the browser, `HttpClient` checks whether it has data in the cache and if so, reuses it instead of making a new HTTP request during initial application rendering. `HttpClient` stops using the cache once an application becomes [stable](api/core/ApplicationRef#isStable) while running in a browser. + +By default, `HttpClient` caches all `HEAD` and `GET` requests which don't contain `Authorization` or `Proxy-Authorization` headers. You can override those settings by using [`withHttpTransferCacheOptions`](api/platform-browser/withHttpTransferCacheOptions) when providing hydration. + +```typescript +bootstrapApplication(AppComponent, { + providers: [ + provideClientHydration(withHttpTransferCacheOptions({ + includePostRequests: true + })) + ] +}); +``` + ## Configuring a server ### Node.js @@ -9506,71 +9561,6 @@ export const reqHandler = createRequestHandler(async (req: Request) => { // ... }); ``` - -## Generate a fully static application - -By default, Angular prerenders your entire application and generates a server file for handling requests. This allows your app to serve pre-rendered content to users. However, if you prefer a fully static site without a server, you can opt out of this behavior by setting the `outputMode` to `static` in your `angular.json` configuration file. - -When `outputMode` is set to `static`, Angular generates pre-rendered HTML files for each route at build time, but it does not generate a server file or require a Node.js server to serve the app. This is useful for deploying to static hosting providers where a backend server is not needed. - -To configure this, update your `angular.json` file as follows: - -```json -{ - "projects": { - "your-app": { - "architect": { - "build": { - "options": { - "outputMode": "static" - } - } - } - } - } -} -``` - -## Caching data when using HttpClient - -[`HttpClient`](api/common/http/HttpClient) cached outgoing network requests when running on the server. This information is serialized and transferred to the browser as part of the initial HTML sent from the server. In the browser, `HttpClient` checks whether it has data in the cache and if so, reuses it instead of making a new HTTP request during initial application rendering. `HttpClient` stops using the cache once an application becomes [stable](api/core/ApplicationRef#isStable) while running in a browser. - -By default, `HttpClient` caches all `HEAD` and `GET` requests which don't contain `Authorization` or `Proxy-Authorization` headers. You can override those settings by using [`withHttpTransferCacheOptions`](api/platform-browser/withHttpTransferCacheOptions) when providing hydration. - -```typescript -bootstrapApplication(AppComponent, { - providers: [ - provideClientHydration(withHttpTransferCacheOptions({ - includePostRequests: true - })) - ] -}); -``` - -## Authoring server-compatible components - -Some common browser APIs and capabilities might not be available on the server. Applications cannot make use of browser-specific global objects like `window`, `document`, `navigator`, or `location` as well as certain properties of `HTMLElement`. - -In general, code which relies on browser-specific symbols should only be executed in the browser, not on the server. This can be enforced through the [`afterEveryRender`](api/core/afterEveryRender) and [`afterNextRender`](api/core/afterNextRender) lifecycle hooks. These are only executed on the browser and skipped on the server. - -```typescript -import { Component, ViewChild, afterNextRender } from '@angular/core'; - -@Component({ - selector: 'my-cmp', - template: `{{ ... }}`, -}) -export class MyComponent { - @ViewChild('content') contentRef: ElementRef; - - constructor() { - afterNextRender(() => { - // Safe to check `scrollHeight` because this will only run in the browser, not the server. - console.log('content height: ' + this.contentRef.nativeElement.scrollHeight); - }); - } -} -``` # Hydration ## What is hydration @@ -10870,7 +10860,7 @@ The `DashboardHeroComponent` is embedded in the `DashboardComponent` template li -The `DashboardHeroComponent` appears in an `*ngFor` repeater, which sets each component's `hero` input property to the looping value and listens for the component's `selected` event. +The `DashboardHeroComponent` appears in an `@for` block, which sets each component's `hero` input property to the looping value and listens for the component's `selected` event. Here's the component's full definition: @@ -11021,7 +11011,7 @@ It creates an `ActivatedRoute` object with the routing information and injects i Here are the services injected into `HeroDetailComponent`: - + The `HeroDetail` component needs the `id` parameter so it can fetch the corresponding hero using the `HeroDetailService`. The component has to get the `id` from the `ActivatedRoute.paramMap` property which is an `Observable`. @@ -11546,7 +11536,7 @@ Here are the most useful `DebugElement` members for testers, in approximate orde | `queryAll` | Calling `queryAll(predicate: Predicate)` returns all `DebugElements` that matches the [predicate](#query-predicate) at any depth in subtree. | | `injector` | The host dependency injector. For example, the root element's component instance injector. | | `componentInstance` | The element's own component instance, if it has one. | -| `context` | An object that provides parent context for this element. Often an ancestor component instance that governs this element.
When an element is repeated within `*ngFor`, the context is an `NgForOf` whose `$implicit` property is the value of the row instance value. For example, the `hero` in `*ngFor="let hero of heroes"`. | +| `context` | An object that provides parent context for this element. Often an ancestor component instance that governs this element.
When an element is repeated within `@for` block, the context is an `RepeaterContext` whose `$implicit` property is the value of the row instance value. For example, the `hero` in `@for(hero of heroes; ...)`. | | `children` | The immediate `DebugElement` children. Walk the tree by descending through `children`. `DebugElement` also has `childNodes`, a list of `DebugNode` objects. `DebugElement` derives from `DebugNode` objects and there are often more nodes than elements. Testers can usually ignore plain nodes. | | `parent` | The `DebugElement` parent. Null if this is the root element. | | `name` | The element tag name, if it is an element. | @@ -11601,7 +11591,7 @@ Many developers can be categorized by one of the following developer type catego | Component harness authors | Developers who maintain some reusable Angular components and want to create a test harness for its users to use in their tests. For example, an author of a third party Angular component library or a developer who maintains a set of common components for a large Angular application. | [Creating component harnesses for your components](guide/testing/creating-component-harnesses) | | Harness environment authors | Developers who want to add support for using component harnesses in additional testing environments. For information on supported testing environments out-of-the-box, see the [test harness environments and loaders](guide/testing/using-component-harnesses#test-harness-environments-and-loaders). | [Adding support for additional testing environments](guide/testing/component-harnesses-testing-environments) | -For the full API reference, please see the [Angular CDK's component harness API reference page](/api/cdk/testing/AsyncOptionPredicate). +For the full API reference, please see the [Angular CDK's component harness API reference page](/api#angular_cdk_testing). # Using component harnesses in tests ## Before you start @@ -11861,7 +11851,7 @@ While `ComponentHarness` subclasses require only the `hostSelector` property, mo Each instance of a `ComponentHarness` subclass represents a particular instance of the corresponding component. You can access the component's host element via the `host() `method from the `ComponentHarness` base class. -`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `ngIf` hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. +`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `@if` block hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. See the [ComponentHarness API reference page](/api/cdk/testing/ComponentHarness) for the full list details of the different `locatorFor` methods.