These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.
This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.
PR Close#61472
`AsyncPipe` would previously promise rejections unhandled and
subscription errors uncaught. This is more or less fine in a Zone-based
application because errors inside the Angular Zone are caught be the
Zone's error trap and reported to `ErrorHandler`. However, in zoneless
applications, these errors are never caught or reported by the FW and
can reach the node process in SSR and cause it to shut down.
BREAKING CHANGE: `AsyncPipe` now directly catches unhandled errors in
subscriptions and promises and reports them to the application's
`ErrorHandler`. For Zone-based applications, these errors would have
been caught by ZoneJS and reported to `ErrorHandler` so the result is
generally the same. The change to the exact mechanism for reporting can
result in differences in test environments that will require test
updates.
PR Close#60057
The keyvalue pipe sorts the entries of the input by key. This has been the subject of debate in the past (https://github.com/angular/angular/issues/42490). The core of the discussions is that it is often desirable (and perhaps expected) that they natural ordering of the input is respected. There are at least two workarounds to restore natural ordering, such as a `compareFn` that simply returns `1` or a custom pipe. However, both of these require code for pipe consumers to maintain or copy around to many places.
Allowing `null` as `compareFn` and treating it as "natural order" is fairly simple to understand, backward compatible and was suggested a few times on https://github.com/angular/angular/issues/42490 where it seemed to be received well. Using `null` is also possible in templates without any component code changes.
PR Close#57487
ISO 8601 defines
* Monday as the first day of the week.
* week 01 is the week with the first Thursday
Therefore:
Sunday Dec 31st 2023 is the last day of the last week of the year : W52 2023.
PR Close#53879
A lot of our tests are wrapped in `{}` which serves no purpose, aside from increasing the nesting level and, in some cases, causing confusion. The braces appear to be a leftover from a time when all tests were wrapped in a `function main() {}`. The function declaration was removed in #21053, but the braces remained, presumably because it was easier to search&replace for `function main()`, but not to remove the braces at the same time.
PR Close#52239
This commit wraps the actual subscription/unsubscription in the `async`
pipe with `untracked`, to ensure that any signal reads/writes which might
take place in `Observable` side effects are not attributed to the template.
Fixes#50382
PR Close#50522
The below error is displayed during some tests
```js
ERROR: 'Unhandled Promise rejection:', 'Cannot read properties of null (reading 'markForCheck')', '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', TypeError: Cannot read properties of null (reading 'markForCheck')
TypeError: Cannot read properties of null (reading 'markForCheck')
at AsyncPipe2._updateLatestValue (http://angular-ci.local:9876/base/dist/legacy-test-bundle.spec.js?49174f830d8743d5c8a9551b77550b859b934291:51947:19)
```
This is caused by the fact that `ref` in `AsyncPipe` is initialized with a value of `null` which causes `_updateLatestValue` to fail since it is not expected to be `null`.
This change ensures that a `ref` is always provided and that all subscriptions are disposed off after each test.
PR Close#49433
This commit introduces a new `DATE_PIPE_DEFAULT_OPTIONS` token, which
can be used to configure default DatePipe options, such as date
format and timezone.
DEPRECATED:
The `DATE_PIPE_DEFAULT_TIMEZONE` token is now deprecated in favor
of the `DATE_PIPE_DEFAULT_OPTIONS` token, which accepts an object
as a value and the timezone can be defined as a field (called `timezone`)
on that object.
PR Close#47157
This commit updates the pipes presents in the `CommonModule` and annotates them with the `standalone: true` flag. With that flag, the pipes can now be imported individually, as well as imported via the `CommonModule`.
PR Close#46401
To mitigate the effect of Observables with memory leak, this change clears
the `ChangeDetectorRef` when the `AsyncPipe` is destroyed. This avoids any
leak within the `Observable` to retain the view data. A test has been added
to verify that this change works correctly with promises that resolve _after_
the pipe has been destroyed.
Note: this is not marked as fix as `AsyncPipe` itself is _not_ leaking any
memory.
Closes#17624
PR Close#46128
This commit finishes the removal of View Engine from the codebase, deleting
those pieces of @angular/compiler which were only used for VE.
Co-Authored-By: JoostK <joost.koehoorn@gmail.com>
PR Close#44368
This commit removes the View Engine runtime. Itself, this change is
relatively straightforward, but it represents the final step in a multi-year
journey. It's only possible due to the hard work of many current and former
team members and collaborators, who are too numerous to list here.
Co-authored-by: Alan Agius <alan.agius4@gmail.com>
Co-authored-by: Andrew Kushnir <akushnir@google.com>
Co-authored-by: Andrew Scott <atscott01@gmail.com>
Co-authored-by: Andrew Seguin <andrewjs@google.com>
Co-authored-by: Cédric Exbrayat <cedric@ninja-squad.com>
Co-authored-by: Charles Lyding <19598772+clydin@users.noreply.github.com>
Co-authored-by: Dave Shevitz <dshevitz@google.com>
Co-authored-by: Doug Parker <dgp1130@users.noreply.github.com>
Co-authored-by: Dylan Hunn <dylhunn@gmail.com>
Co-authored-by: Emma Twersky <emmatwersky@google.com>
Co-authored-by: George Kalpakas <kalpakas.g@gmail.com>
Co-authored-by: Igor Minar <iminar@google.com>
Co-authored-by: Jeremy Elbourn <jelbourn@google.com>
Co-authored-by: Jessica Janiuk <jessicajaniuk@google.com>
Co-authored-by: JiaLiPassion <JiaLi.Passion@gmail.com>
Co-authored-by: Joey Perrott <josephperrott@gmail.com>
Co-authored-by: Joost Koehoorn <joost.koehoorn@gmail.com>
Co-authored-by: Kristiyan Kostadinov <crisbeto@abv.bg>
Co-authored-by: Madleina Scheidegger <mscheid@google.com>
Co-authored-by: Mark Thompson <2554588+MarkTechson@users.noreply.github.com>
Co-authored-by: Minko Gechev <mgechev@gmail.com>
Co-authored-by: Paul Gschwendtner <paulgschwendtner@gmail.com>
Co-authored-by: Pawel Kozlowski <pkozlowski.opensource@gmail.com>
Co-authored-by: Pete Bacon Darwin <pete@bacondarwin.com>
Co-authored-by: Wagner Maciel <wagnermaciel@google.com>
Co-authored-by: Zach Arend <zachzach@google.com>
PR Close#43884
Adds a new injection token called `DATE_PIPE_DEFAULT_TIMEZONE` that allows for the default timezone for all `DatePipe` instances to be specified.
Fixes#43031.
PR Close#43611
We can't update the framework to rxjs7 until version 13, because it contains breaking changes, but we can allow users to opt into it since all of our code should be compatible.
These changes expand the allowed version range of rxjs and add an integration test to verify that we don't get compilation errors. Note that we also have a test that runs the AIO examples against rxjs 7 already (#42660).
Fixes#41897.
PR Close#42991
Previously, if only the `compareFn` changed but the data itself did not, then
the `KeyValuePipe` did not re-sort the output.
Fixes#42819
PR Close#42821
We have some internal proxies for all of the Jasmine functions, as well as some other helpers. This code hasn't been touched in more than 5 years, it can lead to confusion and it isn't really necessary since the same can be achieved using Jasmine.
These changes remove most of the code and clean up our existing unit tests.
PR Close#42177
The `AsyncPipe.transform<T>(emitter)` method must infer the `T`
type from the `emitter` parameter. Since we changed the `AsyncPipe`
to expect a `Subscribable<T>` rather than `Observable<T>` the
`EventEmitter.subscribe()` method needs to have a tighter signature.
Otherwise TypeScript struggles to infer the type and ends up making
it `unknown`.
Fixes#40637
PR Close#40644
As only methods from the Subscribable interface are currently used in the
implementation of the async pipe, it makes sense to make it explicit so
that it works successfully with any other implementation instead of
only Observable.
PR Close#39627
Even in the overloads, state that it can accept `null` and
`undefined`, in order to ensure easy composition with `async`.
Additionally, change the implementation to return `null` on an
`undefined` input, for consistency with other pipes.
BREAKING CHANGE:
The `slice` pipe now returns `null` for the `undefined` input value,
which is consistent with the behavior of most pipes. If you rely on
`undefined` being the result in that case, you now need to check for it
explicitly.
PR Close#37447
As shown in the tests, `KeyValuePipe.transform` can accept
`undefined`, in which case it always returns `null`.
Additionally, the typing for `string` keys can be made generic, so the
comparison function is only required to accept the relevant cases.
Finally, the typing for `number` records now shows that the comparison
function and the result entries will actually receive the string version
of the numeric keys, just as shown in the tests.
BREAKING CHANGE:
The typing of the `keyvalue` pipe has been fixed to report that for
input objects that have `number` keys, the result will contain the
string representation of the keys. This was already the case and the
code has simply been updated to reflect this. Please update the
consumers of the pipe output if they were relying on the incorrect
types. Note that this does not affect use cases where the input values
are `Map`s, so if you need to preserve `number`s, this is an effective
way.
PR Close#37447
I18nPluralPipe can actually accept `null` and `undefined` (which are
convenient for composing it with the async pipe), but it is currently
typed to only accept `number`.
PR Close#37447
Make typing of number pipes stricter to catch some misuses (such as
passing an Observable or an array) at compile time.
BREAKING CHANGE:
The signatures of the number pipes now explicitly state which types are
accepted. This should only cause issues in corner cases, as any other
values would result in runtime exceptions.
PR Close#37447
Make typing of DatePipe stricter to catch some misuses (such as passing
an Observable or an array) at compile time.
BREAKING CHANGE:
The signature of the `date` pipe now explicitly states which types are
accepted. This should only cause issues in corner cases, as any other
values would result in runtime exceptions.
PR Close#37447
`AsyncPipe.transform` will never return `undefined`, even when passed
`undefined` in input, in contrast with what was declared in the
overloads.
Additionally the "actual" method signature can be updated to match the
most generic case, since the implementation does not rely on wrappers
anymore.
BREAKING CHANGE:
The async pipe no longer claims to return `undefined` for an input that
was typed as `undefined`. Note that the code actually returned `null` on
`undefined` inputs. In the unlikely case you were relying on this,
please fix the typing of the consumers of the pipe output.
PR Close#37447
The old implementation of case conversion types can handle several
values which are not strings, but the signature did not reflect this.
The new one reports errors when falsy non-string inputs are given to
the pipe (such as `false` or `0`) and has a new signature which
instead reflects the behaviour on `null` and `undefined`.
Fixes#36259
BREAKING CHANGE:
The case conversion pipes no longer let falsy values through. They now
map both `null` and `undefined` to `null` and raise an exception on
invalid input (`0`, `false`, `NaN`) just like most "common pipes". If
your code required falsy values to pass through, you need to handle them
explicitly.
PR Close#37447
Currently, the `DatePipe` (via `formatDate()`) rounds fractions of a millisecond to the
nearest millisecond. This can cause dates that are less than a millisecond before midnight
to be incremented to the following day.
The [ECMAScript specification](https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.11)
defines that `DateTime` milliseconds should always be rounded down, so that `999.9ms`
becomes `999ms`.
This change brings `formatDate()` and so `DatePipe` inline with the ECMAScript
specification.
Fixes#37989
BREAKING CHANGE:
When passing a date-time formatted string to the `DatePipe` in a format that contains
fractions of a millisecond, the milliseconds will now always be rounded down rather than
to the nearest millisecond.
Most applications will not be affected by this change. If this is not the desired behaviour
then consider pre-processing the string to round the millisecond part before passing
it to the `DatePipe`.
PR Close#38009
Date pipe is giving wrong week number when used with the date format 'w'. If first week(according to Iso) has some days in previous year
Fixes#33961
PR Close#37632
`AsyncPipe` only uses `WrappedValue` when the latest value from the `Promise` or `Observable` is different from the previous one. This is already enough to trigger change detection so the `WrappedValue` is not necessary.
Fixes#29927
BREAKING CHANGE:
This change could result in ExpressionChangedAfterItHasBeenChecked errors that
were not detected before. The error could previously have gone undetected
because two WrappedValues are considered "equal" in all cases for the purposes
of the check, even if their respective unwrapped values are not.
Additionally, `[val]=(observable | async).someProperty` will no longer
trigger change detection if the value of `someProperty` is identical to
the value in the previous emit. If you need to force change detection,
either update the binding to use an object whose reference changes or
subscribe to the observable and call markForCheck as needed.
PR Close#36633
`KeyValuePipe` currently accepts `null` values as well as `Map`s and a
few others. However, due to the way in which TS overloads work, a type
of `T|null` will not be accepted by `KeyValuePipe`'s signatures, even
though both `T` and `null` individually would be.
To make this work, each signature that accepts some type `T` has been
duplicated with a second one below it that accepts a `T|null` and
includes `null` in its return type.
Fixes#35743
PR Close#36093
Default currency code in CurrencyPipe is currently hardcoded to USD
and is not configurable. This commit allows the default currency code
to be configurable by adding a DEFAULT_CURRENCY_CODE injection token.
Example:
```
providers: [{ provide: DEFAULT_CURRENCY_CODE, useValue: "GBP" }]
...
{{ 123.45 | currency }} // outputs £123.45 as opposed to always $123.45 before
```
Closes: #25461
PR Close#32584