mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
refactor(core): add error code for required query results (#54103)
This commit introduces a dedicated error code for queries that require results but none are available. PR Close #54103
This commit is contained in:
parent
20008a6b56
commit
3a2ce9e0a2
6 changed files with 56 additions and 6 deletions
23
adev/src/content/reference/errors/NG0951.md
Normal file
23
adev/src/content/reference/errors/NG0951.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
@name Child query result is required but no value is available.
|
||||
@category runtime
|
||||
@shortDescription Required child query result was accessed before query results were calculated or query has no matches.
|
||||
|
||||
@description
|
||||
Required child query (`contentChild.required` or `viewChild.required`) result was accessed before query results were calculated or query has no matches.
|
||||
|
||||
This can happen in two distinct situations:
|
||||
* query results were accessed before a given query could collect results;
|
||||
* a query was executed but didn't match any nodes and has no results as a consequence.
|
||||
|
||||
Content queries and view queries each calculate their results at different points in time:
|
||||
* `contentChild` results are available after a _host_ view (template where a directive declaring a query is used) is created;
|
||||
* `viewChild` results are available after a template of a component declaring a query is created.
|
||||
|
||||
Accessing query results before they're available results in the error described on this page. Most notably, query results are _never_ available in a constructor of the component or directive declaring a query.
|
||||
|
||||
## Fixing the error
|
||||
|
||||
`contentChild` query results can be accessed in the `AfterContentChecked` lifecycle hook, or later.
|
||||
`viewChild` query results can be accessed in the `AfterViewChecked` lifecycle hook, or later.
|
||||
|
||||
Make sure that a required query matches at least one node and has results at all. You can verify this by accessing query results in the lifecycle hooks listed above.
|
||||
23
aio/content/errors/NG0951.md
Normal file
23
aio/content/errors/NG0951.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
@name Child query result is required but no value is available.
|
||||
@category runtime
|
||||
@shortDescription Required child query result was accessed before query results were calculated or query has no matches.
|
||||
|
||||
@description
|
||||
Required child query (`contentChild.required` or `viewChild.required`) result was accessed before query results were calculated or query has no matches.
|
||||
|
||||
This can happen in two distinct situations:
|
||||
* query results were accessed before a given query could collect results;
|
||||
* a query was executed but didn't match any nodes and has no results as a consequence.
|
||||
|
||||
Content queries and view queries each calculate their results at different points in time:
|
||||
* `contentChild` results are available after a _host_ view (template where a directive declaring a query is used) is created;
|
||||
* `viewChild` results are available after a template of a component declaring a query is created.
|
||||
|
||||
Accessing query results before they're available results in the error described on this page. Most notably, query results are _never_ available in a constructor of the component or directive declaring a query.
|
||||
|
||||
## Fixing the error
|
||||
|
||||
`contentChild` query results can be accessed in the `AfterContentChecked` lifecycle hook, or later.
|
||||
`viewChild` query results can be accessed in the `AfterViewChecked` lifecycle hook, or later.
|
||||
|
||||
Make sure that a required query matches at least one node and has results at all. You can verify this by accessing query results in the lifecycle hooks listed above.
|
||||
|
|
@ -123,6 +123,8 @@ export const enum RuntimeErrorCode {
|
|||
// (undocumented)
|
||||
REQUIRED_INPUT_NO_VALUE = -950,
|
||||
// (undocumented)
|
||||
REQUIRED_QUERY_NO_VALUE = -951,
|
||||
// (undocumented)
|
||||
RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000,
|
||||
// (undocumented)
|
||||
RUNTIME_DEPS_ORPHAN_COMPONENT = 1001,
|
||||
|
|
|
|||
|
|
@ -116,8 +116,9 @@ export const enum RuntimeErrorCode {
|
|||
COMPONENT_ID_COLLISION = -912,
|
||||
IMAGE_PERFORMANCE_WARNING = -913,
|
||||
|
||||
// Signal inputs
|
||||
// Signal integration errors
|
||||
REQUIRED_INPUT_NO_VALUE = -950,
|
||||
REQUIRED_QUERY_NO_VALUE = -951,
|
||||
|
||||
// Runtime dependency tracker errors
|
||||
RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {ComputedNode, createComputed, SIGNAL} from '@angular/core/primitives/signals';
|
||||
|
||||
import {RuntimeError} from '../errors';
|
||||
import {RuntimeError, RuntimeErrorCode} from '../errors';
|
||||
import {unwrapElementRef} from '../linker/element_ref';
|
||||
import {QueryList} from '../linker/query_list';
|
||||
import {EMPTY_ARRAY} from '../util/empty';
|
||||
|
|
@ -48,9 +48,10 @@ function createQuerySignalFn<V>(firstOnly: boolean, required: boolean) {
|
|||
|
||||
const value = refreshSignalQuery<V>(node, firstOnly);
|
||||
|
||||
if (value === undefined && required) {
|
||||
// TODO: add error code add proper message
|
||||
throw new RuntimeError(0, 'no query results yet!');
|
||||
if (required && value === undefined) {
|
||||
throw new RuntimeError(
|
||||
RuntimeErrorCode.REQUIRED_QUERY_NO_VALUE,
|
||||
ngDevMode && 'Child query result is required but no value is available.');
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ describe('queries as signals', () => {
|
|||
const appCmpt = new AppComponent();
|
||||
expect(() => {
|
||||
appCmpt.divEl();
|
||||
}).toThrowError('NG00: no query results yet!');
|
||||
}).toThrowError(/NG0951: Child query result is required but no value is available/);
|
||||
});
|
||||
|
||||
it('should query for multiple elements in a template', () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue