Currently if the `ENVIRONMENT_INITIALIZER` token is not configured with `multi: true` flag, the code fails while trying to iterate over the value. This commit checks whether the `ENVIRONMENT_INITIALIZER` token value type is an array and throws a helpful error message.
PR Close#46829
This commit removes the `Renderer3` experiment which attempted to use the
real DOM API as Angular's renderer. As shown in the diff, having this
experiment around added real code complexity to Angular that could not be
removed by an optimizer.
Since we no longer feel this experiment is worth continuing, we're removing
the `Renderer3` concept and all supporting code.
PR Close#46646
This commit migrates any remaining Angular tests which are using some form
of Renderer3 interfaces. Instead, they're switched to Renderer2.
PR Close#46646
This commit updates the `createEnvironmentInjector` calls in standalone components tests, so that an injector is wired to the DI hierarchy and the code doesn't fall back to using a Renderer3.
PR Close#46633
Remove calls to enableRenderer3 in the functional unit tests.
This effectivelly cuts code paths going through the Renderer3
in the functional tests.
PR Close#46612
The `Renderer3` abstraction in Angular was an experimental code path in Ivy
which uses direct DOM operations instead of the former `Renderer2` path. To
allow `Renderer2` to tree-shake away, `Renderer3` is the default _unless_
`Renderer2` is provided. It was only an experiment, and never meant to be a
production code path.
However, it's possible for `Renderer3` to leak into user code. This commit
prevents that possibility by causing the `Renderer3` path to throw, unless
an explicit function has been called to enable it.
PR Close#46530
This commit updates a set of tests to avoid using hand-written instructions and replace them with TestBed APIs. Some tests were moved to the `acceptance` folder to colocate them with other renderer-related tests.
PR Close#46525
During JIT compilation of standalone components the compiler did not deduplicate
declarations in the imports array, unlike the AOT compiler. This may result in
runtime errors during directive matching, when the same component is found
multiple times resulting in NG0300, for example:
> NG0300: Multiple components match node with tagname mat-form-field: MatFormField and MatFormField.
This commit fixes the issue by deduplicating imports in the JIT compiler.
Relates to https://github.com/angular/angular/issues/46109#issuecomment-1160705031Closes#46109
PR Close#46439
Fixes that the server renderer was producing an invalid `style` attribute when a null value is passed in. Also aligns the behavior with the DOM renderer by removing the attribute when it's empty.
Fixes#46385.
PR Close#46433
Add info to the pipe not found error message so to give some help to the developer for
resolving the problem more efficiently
(Note: this change also distinguishes the case in which the hosting component is standalone)
PR Close#46247
improve code regarding element validation by creating a new file
exporting validation functions and not exporting utils previously
globally available
PR Close#46175
This commit adds the component name into unknown element/property error message, so that it's easier to find a location of a template where the problem happened.
Closes#46080.
PR Close#46160
Prior to this commit, the error message that was produced for the unknown property situation, din't contain extra info on how the problem can be fixed. This commit adds more info to the error message and makes it similar to the one we use during the AOT compilation.
PR Close#46147
improve the error message developers get when adding a standalone
component in the TestBed.configureTestingModule's declarations array,
by making more clear the fact that this error originated from the
TestBed call
resolves#45923
PR Close#45999
Currently for cases when an unknown structural directive is applied to `<ng-template>`s, an error message thrown by the framework doesn't contain a tag name, for example:
```
NG0303: Can't bind to 'unknownDir' since it isn't a known property of 'null'.
```
The underlying reason is that the tag name for the `<ng-template>` is not produced (`null` is useed as a value) by the compiler in case of inline templates and runtime logic relies on this effect.
This commit handles this situation when an error message is thrown, as the fastest way to improve the error message. More refactoring would be needed to avoid relying on the mentioned effect at runtime.
PR Close#46068
update the error message presented during jit compilation when an unrecognized
tag/element is found in a standalone component so that it does not mention
the ngModule anymore
Note: the aot variant is present in PR #45919resolves#45818
PR Close#45920
The `inject()` function was introduced with Ivy to support imperative
injection in factory/constructor contexts, such as directive or service
constructors as well as factory functions defined in `@Injectable` or
`InjectionToken`. However, `inject()` in a component/directive constructor
did not work due to a flaw in the logic for creating the internal factory
for components/directives.
The original intention of this logic was to keep `ɵɵdirectiveInject` tree-
shakable for applications which don't use any component-level DI. However,
this breaks the `inject()` functionality for component/directive
constructors.
This commit fixes that issue and adds tests for all the various cases in
which `inject()` should function. As a result `ɵɵdirectiveInject` is no
longer tree-shakable, but that's totally acceptable as any application that
uses `*ngIf` or `*ngFor` already contains this function. It's possible to
change how `inject()` works to restore this tree-shakability if needed.
PR Close#45991
Allows to provide a TestBed option to throw on unknown properties in templates:
```ts
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(), {
errorOnUnknownProperties: true
}
);
```
The default value of `errorOnUnknownProperties` is `false`, so this is not a breaking change.
PR Close#45853
This commit narrows down acceptable argument types of the
`importProvidersFrom` function. More specifically, it rejects
standalone components as a source of imports.
PR Close#45837
`importProvidersFrom` provides a bridge from the world of NgModule-based DI
configuration to the new, "standalone" world of direct providers and
environment injectors. Early user feedback suggested some confusion around
where this function was supposed to be used, particularly around importing
NgModule-based providers into standalone component `providers` arrays, which
is not the intended use. This confusion is exacerbated by the fact that due
to the unified `Provider` type, this kind of misconfiguration was happily
accepted by the type system.
This commit changes the return type of `importProvidersFrom` to wrap the
returned providers in an opaque type that prevents them from being used in
component provider contexts. This, together with stronger documentation
around the purpose and functionality of `importProvidersFrom`, should
address some of the above confusion.
PR Close#45838
This commit updates the logic to detect a situation when a standalone component is used in the NgModule-based bootstrap (`@NgModule.bootstrap`). Both AOT and JIT compilers are updated to handle this situation.
PR Close#45825
Allows to provide a TestBed option to throw on unknown elements in templates:
```ts
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(), {
errorOnUnknownElements: true
}
);
```
The default value of `errorOnUnknownElements` is `false`, so this is not a breaking change.
PR Close#45479
Allows to provide a TestBed option to throw on unknown elements in templates:
```ts
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(), {
errorOnUnknownElements: true
}
);
```
The default value of `errorOnUnknownElements` is `false`, so this is not a breaking change.
PR Close#45479
This commit adds a test to make sure the NgModule providers are collected correctly by the `importProvidersFrom` function when the `ModuleWithProviders` type is used and some providers are overridden.
PR Close#45787
This commit updates the `EnvironmentInjector` logic to support arrays of providers as an argument(for example, when an injector is created via `createEnvironmentInjector` function).
PR Close#45789
This commits adds verifications assuring that items imported into
standalone components are one of:
- standalone component / directive / pipe;
- NgModule;
- forwardRef resolving to one of the above.
It explicitly disallows modules with providers.
PR Close#45777
There were two problems with the `importProvidersFrom` function related to
`ModuleWithProviders` values:
* The public type did not accept `ModuleWithProviders` values directly.
* The implementation of `walkProviderTree` delegates collection of MWP providers
to its caller, in order for the ordering of such providers to be correct.
However, `importProvidersFrom` was not performing that collection, causing MWP
providers passed in at the top level to be dropped.
PR Close#45722
Add more tests verifying the following conditions:
- discovery of DI providers from exported NgModules
- forwardRef in standalone component imports
PR Close#45709
This commit moves standalone component scoping into the closures for
`directiveDefs` and `pipeDefs` in JIT mode. This is necessary to support
recursive standalone components, which necessarily use a `forwardRef` within
their import cycle. Previously, the JIT compiler for standalone components
attempted immediate `forwardRef` resolution, resulting in infinite recursion.
PR Close#45720
This commit reorganizes the tests around the EnvironmentInjector and its use
for standalone injectors, and adds a number of new test cases.
PR Close#45687
This commit implements the `StandaloneFeature` which provides for the
creation of standalone injectors, for those components which need them. The
feature-based implementation ensures the machinery for standalone injectors
is properly tree-shakable.
PR Close#45687
This commit exposes the `standalone` flag on `@Directive`, `@Component`, and
`@Pipe`, effectively making standalone components a part of Angular's public
API. As part of this operation, it also implements JIT compilation for
standalone types.
Standalone types are Angular-decorated types which act as their own
"declarations", where they would otherwise be declared in an NgModule.
Marking an Angular type as standalone means that it can be used directly in
other standalone components and in NgModules, without needing an associated
NgModule to depend on it. In the case of a standalone component, template
dependencies which would otherwise be specified by an NgModule are instead
specified directly on the component itself, via the `imports` field. Other
standalone types can be imported, as well as NgModules.
PR Close#45687
This commit extracts the `importProvidersFrom` function and associated
machinery into a separate file, as opposed to being colocated with
`R3Injector`. Separating these functions will mitigate potential future
circular dependencies as `importProvidersFrom` starts being used in
different parts of the codebase.
PR Close#45687
This commit adds a new internal scope to `R3Injector` for
`EnvironmentInjector`s specifically. This will allow us to scope services to
the environment side of the injector hierarchy specifically, as opposed to
the `'any'` scope which also includes view-side injectors created via
`Injector.create`. For now, this functionality is not exposed publicly, but
is available to use within `@angular/core` only.
PR Close#45626
This commit exposes a new `EnvironmentInjector` abstraction, which
generalizes the "module injector" concept to injectors that are not based on
NgModules.
An EnvironmentInjector is a conceptual analogue of an `NgModuleRef` - it
represents an injector on the former "module" DI hierarchy in Angular (now
renamed to the "environment injector hierarchy"). Environment injectors are
created via the `createEnvironmentInjector` function from a list of
`Provider`s.
For backwards compatibility with current code using `NgModuleRef`,
`EnvironmentInjector`s are wrapped by an adapter `NgModuleRef`
implementation, so injecting `NgModuleRef` always returns the latest
`EnvironmentInjector`, even if that injector was not based on an NgModule.
Conversely, NgModule-based `NgModuleRef`s created via `createNgModuleRef`
are _also_ `EnvironmentInjector`s.
PR Close#45626
This commit implements the `importProvidersFrom` function that allows
extracting a list of `Provider`s from a list of NgModule types. The
R3Injector which implements DI at the "module" level for Angular is
refactored to use this functionality under the hood.
This commit also implements `INJECTOR_INITIALIZER`, a DI multi-provider
token which is used to run initialization logic when an injector is created.
PR Close#45626