Allows a directive to use the expression passed directly to a property
as a guard instead of filtering the type through a type expression.
This more accurately matches the intent of the ngIf usage of its template
enabling better type inference.
Moved NgIf to using this type of guard instead of a function guard.
Closes: #20967
Structural directives can now specify a type guard that describes
what types can be inferred for an input expression inside the
directive's template.
NgIf was modified to declare an input guard on ngIf.
After this change, `fullTemplateTypeCheck` will infer that
usage of `ngIf` expression inside it's template is truthy.
For example, if a component has a property `person?: Person`
and a template of `<div *ngIf="person"> {{person.name}} </div>`
the compiler will no longer report that `person` might be null or
undefined.
The template compiler will generate code similar to,
```
if (NgIf.ngIfTypeGuard(instance.person)) {
instance.person.name
}
```
to validate the template's use of the interpolation expression.
Calling the type guard in this fashion allows TypeScript to infer
that `person` is non-null.
Fixes: #19756?
PR Close#20702
This is necessary to enable type-based optimizations with Closure.
Without explicity making these options the same named type, Closure
thinks they are different types and cannot disambiguate the `fromObject`
property.
* Remove now unnecessary portions of build.
* Add a compilePackageES5 method to build ES5 from sources
* Rework all package.json and rollup config files to new format
* Remove "extends" from tsconfig-build.json files and fixup compilation roots
PR Close#18541
Today, constructing a new GET request with headers looks like:
const headers = new HttpHeaders({
'My-Header': 'header value',
});
http.get('/url', {headers}).subscribe(...);
This indirection is unnecessary. It'd be more ergonomic to write:
http.get('/url', {headers: {'My-Header': 'header value'}}).subscribe(...);
This commit allows that new syntax, both for HttpHeaders and HttpParams.
In the HttpParams case it also allows construction of HttpParams with a map.
PR Close#18490
BREAKING CHANGE: Because of multiple bugs and browser inconsistencies, we have dropped the intl api in favor of data exported from the Unicode Common Locale Data Repository (CLDR).
Unfortunately we had to change the i18n pipes (date, number, currency, percent) and there are some breaking changes.
1. I18n pipes
* Breaking change:
- By default Angular now only contains locale data for the language `en-US`, if you set the value of `LOCALE_ID` to another locale, you will have to import new locale data for this language because we don't use the intl API anymore.
* Features:
- you don't need to use the intl polyfill for Angular anymore.
- all i18n pipes now have an additional last parameter `locale` which allows you to use a specific locale instead of the one defined in the token `LOCALE_ID` (whose value is `en-US` by default).
- the new locale data extracted from CLDR are now available to developers as well and can be used through an API (which should be especially useful for library authors).
- you can still use the old pipes for now, but their names have been changed and they are no longer included in the `CommonModule`. To use them, you will have to import the `DeprecatedI18NPipesModule` after the `CommonModule` (the order is important):
```ts
import { NgModule } from '@angular/core';
import { CommonModule, DeprecatedI18NPipesModule } from '@angular/common';
@NgModule({
imports: [
CommonModule,
// import deprecated module after
DeprecatedI18NPipesModule
]
})
export class AppModule { }
```
Dont forget that you will still need to import the intl API polyfill if you want to use those deprecated pipes.
2. Date pipe
* Breaking changes:
- the predefined formats (`short`, `shortTime`, `shortDate`, `medium`, ...) now use the patterns given by CLDR (like it was in AngularJS) instead of the ones from the intl API. You might notice some changes, e.g. `shortDate` will be `8/15/17` instead of `8/15/2017` for `en-US`.
- the narrow version of eras is now `GGGGG` instead of `G`, the format `G` is now similar to `GG` and `GGG`.
- the narrow version of months is now `MMMMM` instead of `L`, the format `L` is now the short standalone version of months.
- the narrow version of the week day is now `EEEEE` instead of `E`, the format `E` is now similar to `EE` and `EEE`.
- the timezone `z` will now fallback to `O` and output `GMT+1` instead of the complete zone name (e.g. `Pacific Standard Time`), this is because the quantity of data required to have all the zone names in all of the existing locales is too big.
- the timezone `Z` will now output the ISO8601 basic format, e.g. `+0100`, you should now use `ZZZZ` to get `GMT+01:00`.
| Field type | Format | Example value | v4 | v5 |
|------------|---------------|-----------------------|----|---------------|
| Eras | Narrow | A for AD | G | GGGGG |
| Months | Narrow | S for September | L | MMMMM |
| Week day | Narrow | M for Monday | E | EEEEE |
| Timezone | Long location | Pacific Standard Time | z | Not available |
| Timezone | Long GMT | GMT+01:00 | Z | ZZZZ |
* Features
- new predefined formats `long`, `full`, `longTime`, `fullTime`.
- the format `yyy` is now supported, e.g. the year `52` will be `052` and the year `2017` will be `2017`.
- standalone months are now supported with the formats `L` to `LLLLL`.
- week of the year is now supported with the formats `w` and `ww`, e.g. weeks `5` and `05`.
- week of the month is now supported with the format `W`, e.g. week `3`.
- fractional seconds are now supported with the format `S` to `SSS`.
- day periods for AM/PM now supports additional formats `aa`, `aaa`, `aaaa` and `aaaaa`. The formats `a` to `aaa` are similar, while `aaaa` is the wide version if available (e.g. `ante meridiem` for `am`), or equivalent to `a` otherwise, and `aaaaa` is the narrow version (e.g. `a` for `am`).
- extra day periods are now supported with the formats `b` to `bbbbb` (and `B` to `BBBBB` for the standalone equivalents), e.g. `morning`, `noon`, `afternoon`, ....
- the short non-localized timezones are now available with the format `O` to `OOOO`. The formats `O` to `OOO` will output `GMT+1` while the format `OOOO` will be `GMT+01:00`.
- the ISO8601 basic time zones are now available with the formats `Z` to `ZZZZZ`. The formats `Z` to `ZZZ` will output `+0100`, while the format `ZZZZ` will be `GMT+01:00` and `ZZZZZ` will be `+01:00`.
* Bug fixes
- the date pipe will now work exactly the same across all browsers, which will fix a lot of bugs for safari and IE.
- eras can now be used on their own without the date, e.g. the format `GG` will be `AD` instead of `8 15, 2017 AD`.
3. Currency pipe
* Breaking change:
- the default value for `symbolDisplay` is now `symbol` instead of `code`. This means that by default you will see `$4.99` for `en-US` instead of `USD4.99` previously.
* Deprecation:
- the second parameter of the currency pipe (`symbolDisplay`) is no longer a boolean, it now takes the values `code`, `symbol` or `symbol-narrow`. A boolean value is still valid for now, but it is deprecated and it will print a warning message in the console.
* Features:
- you can now choose between `code`, `symbol` or `symbol-narrow` which gives you access to more options for some currencies (e.g. the canadian dollar with the code `CAD` has the symbol `CA$` and the symbol-narrow `$`).
4. Percent pipe
* Breaking change
- if you don't specify the number of digits to round to, the local format will be used (and it usually rounds numbers to 0 digits, instead of not rounding previously), e.g. `{{ 3.141592 | percent }}` will output `314%` for the locale `en-US` instead of `314.1592%` previously.
Fixes#10809, #9524, #7008, #9324, #7590, #6724, #3429, #17576, #17478, #17319, #17200, #16838, #16624, #16625, #16591, #14131, #12632, #11376, #11187
PR Close#18284
BREAKING CHANGE: `NgFor` has been removed as it was deprecated since v4. Use `NgForOf` instead. This does not impact the use of`*ngFor` in your templates.
PR Close#18758
BREAKING CHANGE: `NgTemplateOutlet#ngOutletContext` has been removed as it was deprecated since v4. Use `NgTemplateOutlet#ngTemplateOutletContext` instead.
PR Close#18780
HttpClient is an evolution of the existing Angular HTTP API, which exists
alongside of it in a separate package, @angular/common/http. This structure
ensures that existing codebases can slowly migrate to the new API.
The new API improves significantly on the ergonomics and features of the legacy
API. A partial list of new features includes:
* Typed, synchronous response body access, including support for JSON body types
* JSON is an assumed default and no longer needs to be explicitly parsed
* Interceptors allow middleware logic to be inserted into the pipeline
* Immutable request/response objects
* Progress events for both request upload and response download
* Post-request verification & flush based testing framework
* feat(common): support `as` syntax in template/* bindings
Closes#15020
Showing the new and the equivalent old syntax.
- `*ngIf="exp as var1”`
=> `*ngIf="exp; let var1 = ngIf”`
- `*ngFor="var item of itemsStream |async as items”`
=> `*ngFor="var item of itemsStream |async; let items = ngForOf”`
* feat(common): convert ngIf to use `*ngIf="exp as local“` syntax
* feat(common): convert ngForOf to use `*ngFor=“let i of exp as local“` syntax
* feat(common): expose NgForOfContext and NgIfContext
DEPRECATION:
Use `RouterModule.forRoot(routes, {initialNavigation: 'enabled'})` instead of
`RouterModule.forRoot(routes, {initialNavigtaion: true})`.
Before doing this, move the initialization logic affecting the router
from the bootstrapped component to the boostrapped module.
Similarly, use `RouterModule.forRoot(routes, {initialNavigation: 'disabled'})`
instead of `RouterModule.forRoot(routes, {initialNavigation: false})`.
Deprecated options: 'legacy_enabled', `true` (same as 'legacy_enabled'),
'legacy_disabled', `false` (same as 'legacy_disabled').
The "Router Initial Navigation" design document covers this change.
Read more here:
https://docs.google.com/document/d/1Hlw1fPaVs-PCj5KPeJRKhrQGAvFOxdvTlwAcnZosu5A/edit?usp=sharing
TypeScript compiler will now build to ES2015 code and modules. Babili is used to minify ES2015
code, providing an initial optimization that we couldn't previously get just from Uglify. Uses
Babel to convert ES2015 to UMD/ES5 code, and Uglify to minimize the output.
BREAKING CHANGE: Classes that derive from `AsyncPipe` and override
`transform()` might not compile correctly. Use of `async` pipe in
templates is unaffected.
Mitigation: Update derived classes of `AsyncPipe` that override
`transform()` to include the type parameter overloads.
Related to #12398
PR Close#14367
BREAKING CHANGE:
- `KeyValueDifferFactory` and `IterableDifferFactory` no longer have `ChangeDetectorRef` as
a parameter. It was not used and has been there for historical reasons. If you call
`DifferFactory.create(...)` remove the `ChangeDetectorRef` argument.
Note, this affects the underlying class and should not affect usage.
DEPRECATION:
- the `NgFor` class is now deprecated. Use `NgForOf<T>` instead.
IMPORTANT: Only the `NgFor` class is deprecated, not the `ngFor`
directive. The `*ngFor` and related directives are unaffected by
this change as references to the `NgFor` class generated from
templates will be automatically converted to references to
`NgForOf<T>` without requiring any template modifications.
- `TrackByFn` is now deprecated. Use `TrackByFunction<T>` instead.
Migration:
- Replace direct references to the `NgFor` class to `NgForOf<any>`.
- Replace references to `TrackByFn` to `TrackByFunction<any>`.
BREAKING CHANGE:
A definition of `Iterable<T>` is now required to correctly compile
Angular applications. Support for `Iterable<T>` is not required at
runtime but a type definition `Iterable<T>` must be available.
`NgFor`, and now `NgForOf<T>`, already supports `Iterable<T>` at
runtime. With this change the type definition is updated to reflect
this support.
Migration:
- add "es2015.iterable.ts" to your tsconfig.json "libs" fields.
Part of #12398
PR Close#14104
Allow NgComponentOutlet to dynamically load a module, then load a component from
that module. Useful for lazy loading code, then add the lazy loaded code to the
page using NgComponentOutlet.
Closes#14043
- Introduce `InjectionToken<T>` which is a parameterized and type-safe
version of `OpaqueToken`.
DEPRECATION:
- `OpaqueToken` is now deprecated, use `InjectionToken<T>` instead.
- `Injector.get(token: any, notFoundValue?: any): any` is now deprecated
use the same method which is now overloaded as
`Injector.get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T): T;`.
Migration
- Replace `OpaqueToken` with `InjectionToken<?>` and parameterize it.
- Migrate your code to only use `Type<?>` or `InjectionToken<?>` as
injection tokens. Using other tokens will not be supported in the
future.
BREAKING CHANGE:
- Because `injector.get()` is now parameterize it is possible that code
which used to work no longer type checks. Example would be if one
injects `Foo` but configures it as `{provide: Foo, useClass: MockFoo}`.
The injection instance will be that of `MockFoo` but the type will be
`Foo` instead of `any` as in the past. This means that it was possible
to call a method on `MockFoo` in the past which now will fail type
check. See this example:
```
class Foo {}
class MockFoo extends Foo {
setupMock();
}
var PROVIDERS = [
{provide: Foo, useClass: MockFoo}
];
...
function myTest(injector: Injector) {
var foo = injector.get(Foo);
// This line used to work since `foo` used to be `any` before this
// change, it will now be `Foo`, and `Foo` does not have `setUpMock()`.
// The fix is to downcast: `injector.get(Foo) as MockFoo`.
foo.setUpMock();
}
```
PR Close#13785
NgIf syntax has been extended to support else clause to display template
when the condition is false. In addition the condition value can now
be stored in local variable, for later reuse. This is especially useful
when used with the `async` pipe.
Example:
```
<div *ngIf="userObservable | async; else loading; let user">
Hello {{user.last}}, {{user.first}}!
</div>
<template #loading>Waiting...</template>
```
closes#13061closes#13297
Closes#9751
BREAKING CHANGE:
These forms of providers are no longer accepted:
bind(MyClass).toFactory(...)
new Provider(MyClass, toFactory: ...)
We now only accept:
{provider: MyClass, toFactory: ...}
BREAKING CHANGE:
The deprecated forms APIs in @angular/common have been removed. Please update to the new forms API in @angular/forms. See angular.io for more information.
Closes#9729
BREAKING CHANGE:
`Type` is now `Type<T>` which means that in most cases you have to
use `Type<any>` in place of `Type`.
We don't expect that any user applications use the `Type` type.
Prior to this fix [ngClass] would remove all dynamic classes
when destroyed. It's essential that classes are persisted such
that remove-based animations will still be stylistically correct.
This patch fixes this issue.
Closes#10008Closes#10303
This contains major changes to the compiler, bootstrap of the platforms
and test environment initialization.
Main part of #10043Closes#10164
BREAKING CHANGE:
- Semantics and name of `@AppModule` (now `@NgModule`) changed quite a bit.
This is actually not breaking as `@AppModules` were not part of rc.4.
We will have detailed docs on `@NgModule` separately.
- `coreLoadAndBootstrap` and `coreBootstrap` can't be used any more (without migration support).
Use `bootstrapModule` / `bootstrapModuleFactory` instead.
- All Components listed in routes have to be part of the `declarations` of an NgModule.
Either directly on the bootstrap module / lazy loaded module, or in an NgModule imported by them.
Closes#9732
BREAKING CHANGE:
We have removed the deprecated form directives from the built-in platform directive list, so apps are not required to package forms with their app. This also makes forms friendly to offline compilation.
Instead, we have exposed three modules:
OLD API:
- `DeprecatedFormsModule`
NEW API:
- `FormsModule`
- `ReactiveFormsModule`
If you provide one of these modules, the default forms directives and providers from that module will be available to you app-wide. Note: You can provide both the `FormsModule` and the `ReactiveFormsModule` together if you like, but they are fully-functional separately.
**Before:**
```ts
import {disableDeprecatedForms, provideForms} from @angular/forms;
bootstrap(App, [
disableDeprecatedForms(),
provideForms()
]);
```
**After:**
```ts
import {DeprecatedFormsModule} from @angular/common;
bootstrap(App, {modules: [DeprecatedFormsModule] });
```
-OR-
```ts
import {FormsModule} from @angular/forms;
bootstrap(App, {modules: [FormsModule] });
```
-OR-
```ts
import {ReactiveFormsModule} from @angular/forms;
bootstrap(App, {modules: [ReactiveFormsModule] });
```
You can also choose not to provide any forms module and run your app without forms.
Or you can choose not to provide any forms module *and* provide form directives at will. This will allow you to use the deprecatedForms API for some components and not others.
```
import {FORM_DIRECTIVES, FORM_PROVIDERS} from @angular/forms;
@Component({
selector: some-comp,
directives: [FORM_DIRECTIVES],
providers: [FORM_PROVIDERS]
})
class SomeComp
```
- ts-api-guardian will now error if a new public symbol is added with a stability marker (`@stable`, `@experimental`, `@deprecated`)
- DomEventsPlugin and KeyEventsPlugin were removed from public api surface - these classes is an implementation detail
- deprecated BROWSER_PROVIDERS was removed completely
- `@angular/compiler` was removed from the ts-api-guardian check since this package shouldn't contain anything that users need to directly import
- the rest of the api surface was conservatively marked as stable or experimental
BREAKING CHANGES: DomEventsPlugin and KeyEventsPlugin previously exported from core are no longer public - these classes are implementation detail.
Previously deprecated BROWSER_PROVIDERS was completely removed from platform-browser.
Closes#9236Closes#9235
Ref #9234
BREAKING CHANGE:
MockLocationStrategy was intended to be internal only and is now removed
from the `@angular/common/testing` public api.
Use `SpyLocation` from `@angular/common/testing` for location testing.