Compare commits

...

108 Commits

Author SHA1 Message Date
ec6ff1155b feat(core): upgrade rxjs to 6.0.0-alpha.4 2018-03-14 12:38:02 -07:00
ed78457c38 build: temporarily disable tests that depend on angular-in-memory-web-api
angular-in-memory-web-api is not yet compatible with rxjs v6 and rxjs v6 backwards compatibility package is not yet ready to be used.
2018-03-14 12:38:02 -07:00
8e3b940461 build: temporarily disable offline_compiler_test.sh 2018-03-14 12:38:02 -07:00
804d8c89d4 build: temporarily increase payload size limit for cli-hello-world until we update cli to v6 2018-03-14 12:38:02 -07:00
ea1dd3a2fc ci: improve logging when running aio/examples e2e tests 2018-03-14 12:38:02 -07:00
a5e6c64f25 build: update to zone.js@0.8.20 2018-03-14 12:38:02 -07:00
57760c8d20 build: remove obsolete rollup-test 2018-03-14 12:38:02 -07:00
683066fef1 build(aio): temporarily use RxJS from root node_modules/ when using local packages 2018-03-14 12:38:02 -07:00
f5a98f41fe fix(core): remove core animation import symbols (#22692)
This patch removes the deprecated support for animation
symbol imports from @angular/core.

BREAKING CHANGE: it is no longer possible to import
animation-related functions from @angular/core. All
animation symbols must now be imported from @angular/animations.

PR Close #22692
2018-03-14 12:23:51 -07:00
c09bd67aee fix(ivy): fix views manipulation logic (#22656)
This commit fixes a bug that would result in views insert / remove
even if a view needed only refresh operation.

The crux of the bug was that we were looking for a view to update
only in the LContainer.nextIndex position. This is incorrect as a
view with a given block id could be present later in the views
array (this happens if we about to remove a view in the middle of
the views array).

The code in this fix searches for a view to update in the views array and
can remove views in the middle of the views collection. Previously we
would remove views at the end of the collection only.

PR Close #22656
2018-03-14 12:07:15 -07:00
9df13add5d docs(aio): add ng-japan 2018 to events (#22750)
ng-japan 2018 will be held at June 16 in Tokyo, Japan! 

https://ngjapan.org/en.html
PR Close #22750
2018-03-14 10:59:55 -07:00
049757b237 fix(aio): constrain error logging to improve reporting (#22713)
The `Logger.error()` method now only accepts a single `Error` parameter
and passes this through to the error handler.
This allows the error handler to serialize the error more accurately.

The various places that use `Logger.error()` have been updated.

See #21943#issuecomment-370230047

PR Close #22713
2018-03-14 10:52:11 -07:00
1f9734315d docs: testing - highlight dispatchEvent (#22726)
PR Close #22726
2018-03-14 10:21:41 -07:00
6f0dad1710 build(aio): render doc-gen issues in overview dump (#22675)
Related to #22138

PR Close #22675
2018-03-14 10:20:30 -07:00
37fedd001c feat(core): add task tracking to Testability (#16863)
Allow passing an optional timeout to Testability's whenStable(). If
specified, if Angular is not stable before the timeout is hit, the
done callback will be invoked with a list of pending macrotasks.

Also, allows an optional update callback, which will be invoked whenever
the set of pending macrotasks changes. If this callback returns true,
the timeout will be cancelled and the done callback will not be invoked.

If the optional parameters are not passed, whenStable() will work
as it did before, whether or not the task tracking zone spec is
available.

This change also migrates the Testability unit tests off the deprecated
AsyncTestCompleter.

PR Close #16863
2018-03-14 08:48:48 -07:00
b1365d1fa8 refactor(ivy): remove directiveRefresh instruction (#22745)
PR Close #22745
2018-03-13 23:29:21 -07:00
4ac606b419 docs(compiler): fix spelling errors (#22704)
PR Close #22704
2018-03-13 21:45:13 -07:00
51027d73cc fix(ivy): Update rollup rule to prevent inlining symbols in debug. (#22747)
The new rollup rule disables inlining symbols in debug mode. This makes 
it look as if there would be more symbols but in reality these are the
symbols which are no longer being inlined.
PR Close #22747
2018-03-13 19:58:30 -07:00
48636f3e85 build(aio): compute stability and deprecate @stable tag (#22674)
Closes #22635

PR Close #22674
2018-03-13 19:55:00 -07:00
bd9d4df735 refactor(ivy): remove inputsPropertyName (#22716)
Closes #22591

PR Close #22716
2018-03-13 13:26:15 -07:00
34e355a3b0 build(bazel): ng_package rxjs/operators rollup config (#22744)
PR Close #22744
2018-03-13 12:12:11 -07:00
58b94e6f5e feat(animations): expose element and params within transition matchers (#22693)
PR Close #22693
2018-03-13 09:42:24 -07:00
db56836425 feat: tree-shakeable providers API updates (#22655)
Rename @Injectable({scope -> providedIn}).

Instead of {providedIn: APP_ROOT_SCOPE}, accept {providedIn: 'root'}.
Also, {providedIn: null} implies the injectable should not be added
to any scope.

PR Close #22655
2018-03-13 09:28:05 -07:00
21e44c6ba9 ci: add alexeagle to pullapprove root group (#22724)
PR Close #22724
2018-03-12 16:23:58 -07:00
f5d75d8efd build: fix postinstall for windows (#22720)
PR Close #22720
2018-03-12 15:11:25 -07:00
6e00410e1c fix(compiler-cli): annotate Ivy fields as @nocollapse in closure mode (#22691)
Closure has a transformation which turns:

Service.ngInjectableDef = ...;

into:

Service$ngInjectableDef = ...;

This transformation obviously breaks Ivy in a major way. The solution is
to annotate the fields as @nocollapse. However, Typescript appears to ignore
synthetic comments added to a node during a transformation, so the "right"
way to add these comments doesn't work.

As an interim measure, a post-processing step just before the compiled JS is
written to disk appends the correct comments with a regular expression.

PR Close #22691
2018-03-12 14:34:22 -07:00
f95730b8e2 fix(ivy): elements properties should not be stringified (#22683)
PR Close #22683
2018-03-12 13:16:05 -07:00
cd58c0a6d9 build(aio): remove unwanted overview headings (#22681)
PR Close #22681
2018-03-12 11:23:47 -07:00
38fef1588d build(aio): move "see also" block to export-base template (#22681)
This makes it easier for all the API docs to display "see also" links
in a consitent manner.

PR Close #22681
2018-03-12 11:23:46 -07:00
3f70aba272 fix(compiler-cli): disableTypeScriptVersionCheck should be applied even for older tsc versions (#22669)
Previously the flag would only disable the check in the case we tried to use newer tsc version.

In g3 we sometimes take a while to update tsc, but as a prerequisite of that Angular needs to be
updated first. This change enables us to update Angular and use it in g3 while g3 is being update
to the required tsc. Of course extra care is required when this check is disabled, but since we
control everything in g3, it's on us to get this right.

I don't see any preexisting tests for this, and I'm not sure how to write them right now.
I filed https://github.com/angular/angular/issues/22699

PR Close #22669
2018-03-12 09:27:24 -07:00
eb6fb2d8f9 build: switch from uglify-js to uglify-es (#22669)
This enables us to minify ES2015 code.

PR Close #22669
2018-03-12 09:27:24 -07:00
c602563589 feat(compiler-cli): require node 8 as runtime engine (#22669)
This is not expected to be a breaking change for anyone who's on Node LTS (currently v8)
and aligns @angular/compilar-cli with @angular/cli's runtime requirements.

PR Close #22669
2018-03-12 09:27:23 -07:00
8449eb8d62 build: upgrade to TypeScript 2.7 (#22669)
Fixes: #21571

PR Close #22669
2018-03-12 09:27:23 -07:00
a225b48482 build: introduce a temporary patch to make node_modules/rxjs compile with typescript 2.7 (#22669)
This patch can be removed once we update to rxjs v6. See #22573.

PR Close #22669
2018-03-12 09:27:23 -07:00
129d1e0fb1 build: add postinstall-patches.js script suitable for postinstall patching of dependencies (#22669)
Because sometimes one has to do what one has to do...

PR Close #22669
2018-03-12 09:27:23 -07:00
aa7dba244b feat(ivy): support checkNoChanges (#22710)
PR Close #22710
2018-03-11 22:16:38 -07:00
0bf6fa5b32 fix(router): correct over-encoding of URL fragment (#22687)
Relates to: #10280 #22337

PR Close #22687
2018-03-11 22:15:01 -07:00
40315bef3d fix(compiler-cli): enableResourceInlining handles both styles and styleUrls (#22688)
When both are present, the inlined styles are appended to the end of the styles

PR Close #22688
2018-03-11 22:14:32 -07:00
123efba388 fix(compiler-cli): resolve resource URLs before loading them under enableResourceInlining (#22688)
Also turn on the feature for Bazel ng_module rules

PR Close #22688
2018-03-11 22:14:31 -07:00
fa451bcd19 feat(ivy): support markForCheck (#22690)
PR Close #22690
2018-03-09 20:29:05 -08:00
0d8deb0795 fix(compiler-cli): generate proper exports.* identifiers in cjs output (#22564)
When the compiler generates a reference to an exported variable in the
same file, it inserts a synthetic ts.Identifier node. In CommonJS
output, this synthetic node would not be properly rewritten with an
`exports.` prefix.

This change sets the TS original node property on the synthetic node
we generate, which ensures TS knows to rewrite it in CommonJS output.

PR Close #22564
2018-03-09 13:09:57 -08:00
e8326e600d fix: overloading a function doesn't generate all of the signatures (#22569)
PR Close #22569
2018-03-09 13:07:36 -08:00
b5be18f405 feat(compiler-cli): add resource inlining to ngc (#22615)
When angularCompilerOptions { enableResourceInlining: true }, we replace all templateUrl and styleUrls properties in @Component with template/styles

PR Close #22615
2018-03-09 09:15:12 -08:00
1e6cc42a01 test: migrate remaining public-api tests to Bazel (#22639)
We now create npm packages to cover all the public api assertions in tools/public_api_guard.
We no longer depend on ts-api-guardian from npm - it is now stale since the repository was archived.
There is no longer a gulp task to enforce or accept the public API, this is in CircleCI as part of running all bazel test targets.

PR Close #22639
2018-03-09 09:11:40 -08:00
b26a90567c feat(ivy): support attaching and detaching views from change detection (#22670)
PR Close #22670
2018-03-08 23:44:33 -08:00
b0b9ca3386 feat(ivy): produce Renderer2 back-patching and factories. (#22506)
Produces back-patch as described in the #22235 and referenced in #22480.

This just contains the compiler implementations and the corresponding unit
tests. Connecting the dots as described in #22480 will be in a follow on
change.

PR Close #22506
2018-03-08 22:39:07 -08:00
5412e10bcd docs(core): replace ancient live demos (#22665)
PR Close #22665
2018-03-08 16:43:14 -08:00
489fec1299 feat: update tslib to 1.9.0 (#22667)
BREAKING CHANGE: after this change, npm and yarn will issue incompatible peerDependencies warning

We don't expect this to actually break an application, but the application/library package.json
will need to be updated to provide tslib 1.9.0 or higher.

PR Close #22667
2018-03-08 16:42:34 -08:00
2fee5cc095 test(ivy): add injection canonical specs (#22595)
PR Close #22595
2018-03-08 12:09:39 -08:00
f13f4db9dc refactor(ivy): fix rebase error (#22661)
PR Close #22661
2018-03-08 11:37:42 -08:00
2ca77d80ec docs: refactor revert() and call to lifecylce hook, edit doc to changes (#22094)
PR Close #22094
2018-03-08 10:58:42 -08:00
73c203fda9 feat(ivy): support host attribute and property bindings (#22334)
PR Close #22334
2018-03-08 10:57:30 -08:00
c499c8f4db build: update angular-bot g3sync paths (#22637)
We already trimmed these paths from the g3sync

PR Close #22637
2018-03-08 10:55:15 -08:00
4c089c1d93 feat(ivy): support ChangeDetectorRef.detectChanges (#22614)
PR Close #22614
2018-03-07 21:08:25 -08:00
d485346d3c fix(ivy): lifecycle hooks should be queued for root component (#22614)
PR Close #22614
2018-03-07 21:08:25 -08:00
8407fcc979 ci: double our cores on CircleCI (#22641)
This should cut our build time in ~half, assuming it's widely parallel.
See
https://circleci.com/docs/2.0/configuration-reference/#resource_class

Also enable bazel repository caching, and store the external
repositories in the CircleCI cache for later builds.

PR Close #22641
2018-03-07 21:00:03 -08:00
f64ee15487 feat(ivy): implement pipes (#22254)
PR Close #22254
2018-03-07 20:58:48 -08:00
5d4fa7f0c8 test(ivy): add canonical examples of bindings on elements (#22403)
PR Close #22403
2018-03-07 20:55:49 -08:00
8fb34bcd43 refactor(forms): deprecate ngModel usage on same field as formControl (#22633)
Support for using the `ngModel` input property and `ngModelChange`
event with reactive form directives has been deprecated in
Angular v6 and will be removed in Angular v7.

Now deprecated:
```html
<input [formControl]="control" [(ngModel)]="value">
```

```ts
this.value = 'some value';
```

This has been deprecated for a few reasons. First, developers have
found this pattern confusing. It seems like the actual `ngModel`
directive is being used, but in fact it's an input/output property
named `ngModel` on the reactive form directive that simply approximates
(some of) its behavior. Specifically, it allows getting/setting the
value and intercepting value events. However, some of `ngModel`'s other
features - like delaying updates with`ngModelOptions` or exporting the
directive - simply don't work, which has understandably caused some
confusion.

In addition, this pattern mixes template-driven and reactive forms
strategies, which we generally don't recommend because it doesn't take
advantage of the full benefits of either strategy. Setting the value in
the template violates the template-agnostic principles behind reactive
forms, whereas adding a FormControl/FormGroup layer in the class removes
the convenience of defining forms in the template.

To update your code before v7, you'll want to decide whether to stick
with reactive form directives (and get/set values using reactive forms
patterns) or switch over to template-driven directives.

After (choice 1 - use reactive forms):

```html
<input [formControl]="control">
```

```ts
this.control.setValue('some value');
```

After (choice 2 - use template-driven forms):

```html
<input [(ngModel)]="value">
```

```ts
this.value = 'some value';
```

You can also choose to silence this warning by providing a config for
`ReactiveFormsModule` at import time:

```ts
imports: [
  ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
```

Alternatively, you can choose to surface a separate warning for each
instance of this pattern with a config value of `"always"`. This may
help to track down where in the code the pattern is being used as the
code is being updated.

Note: `warnOnNgModelWithFormControl` is set up as deprecated so that it
can be removed in v7 when it is no longer needed. This will not display
properly in API docs yet because dgeni doesn't yet support deprecating
properties in object literals, but we have an open issue to resolve the
discrepancy here: https://github.com/angular/angular/issues/22640.

PR Close #22633
2018-03-07 20:47:53 -08:00
6d1367d297 feat(ivy): provide sanitization methods which can be tree shaken (#22540)
By providing a top level sanitization methods (rather than service) the
compiler can generate calls into the methods only when needed. This makes
the methods tree shakable.

PR Close #22540
2018-03-07 18:24:07 -08:00
538f1d980f refactor(core): move sanitization into core (#22540)
This is in preparation of having Ivy have sanitization inline.

PR Close #22540
2018-03-07 18:24:06 -08:00
065bcc5aad docs: add HeroService to code tabs and fix headers (#22373)
PR Close #22373
2018-03-07 18:20:53 -08:00
8ad4ae0a07 docs: add changelog for 6.0.0-beta.7 2018-03-07 14:59:33 -08:00
ffc6ee0086 release: cut the 6.0.0-beta.7 release 2018-03-07 14:57:04 -08:00
78167915ee build(common): export locale data as commonjs instead of es2015 (#20624)
PR Close #20624
2018-03-07 14:33:45 -08:00
ad8fb8484f test: include router in public_api_guard tests (#22628)
Remove duplicate public api testing from the gulp task.

PR Close #22628
2018-03-07 10:56:27 -08:00
ce649f725f build: add a ng_package rule for @angular/router (#22628)
PR Close #22628
2018-03-07 10:56:27 -08:00
fcb8c492d6 build: add an npm_package rule for @angular/bazel (#22628)
PR Close #22628
2018-03-07 10:56:27 -08:00
4f744cc66f docs: update RELEASE_SCHEDULE.md by pushing out v6 rc by one week
We are pushing RC and Final out by one week because of RxJS v6 complications that are blocking the release. No further delays are currently expected.
2018-03-07 10:50:55 -08:00
505ae752b6 docs(aio): update deprecated Http reference to HttpClientModule, remove Http reference because another context is used (#21984)
docs(aio): change HttpClientModule reference to HttpClient

docs(aio): capitalize Http to HTTP

docs(aio): fix typo mistake in 'universal' guide

docs(aio): gets rid of the parentheses and the "e.g." in 'universal' guide

PR Close #21984
2018-03-06 15:03:54 -08:00
363dfa5437 test(ivy): Back patch example (#22235)
PR Close #22235
2018-03-06 15:02:02 -08:00
b3d1761825 build(aio): compute and display short descriptions in methods (#22583)
Previously only export docs were displaying a short description.
Now methods in classes and interfaces also compute and render
the short description.

Closes #22500

PR Close #22583
2018-03-06 11:05:21 -08:00
d0db9ded90 docs: fix cli-quickstart doc and specs (#22338)
* tests were broken
* incorrect instructions.
* didn't match current CLI template for new project

PR Close #22338
2018-03-06 09:41:53 -08:00
4c40812b71 fix(bazel): fixes for ng_package on Windows (#22597)
PR Close #22597
2018-03-06 07:52:48 -08:00
fa974c7d4e fix(router): fix URL serialization so special characters are only encoded where needed (#22337)
This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on RFC 3986 and resolves issues such as the above #10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* URI fragments will now serialize the same as query strings
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

Fixes: #10280

PR Close #22337
2018-03-06 06:58:08 -08:00
2c75acc5b3 feat(ivy): add support for the ngProjectAs attribute (#22498)
PR Close #22498
2018-03-06 06:55:51 -08:00
f86d8ae0fd docs(compiler): fix a line about ivy library (#22579)
PR Close #22579
2018-03-05 21:25:43 -08:00
94bc277b1b fix(aio): tidy up embedded ToC styling (#22570)
The spacing didn't work well when the screen was narrow.

PR Close #22570
2018-03-05 21:25:09 -08:00
8ea4c57174 fix(aio): reposition and shrink the API badges (#22570)
Closes #22130

PR Close #22570
2018-03-05 21:25:09 -08:00
53b0fe8144 feat(aio): allow template to position embedded ToC (#22570)
Previously the doc-viewer would insert an embedded `<aio-toc>` element
into the DOM directly after the H1 element. Now it will not do this
if there is already a such element in the doc contents.

This allows the content-author/template-developer to position the ToC
for specific cases.

PR Close #22570
2018-03-05 21:25:09 -08:00
2a1e3d191f docs: add info about the WebStorm plugin to BAZEL.md (#22572)
PR Close #22572
2018-03-05 21:24:23 -08:00
2c2b62f45f fix(ivy): preventDefault when listener returns false (#22529)
Closes #22495

PR Close #22529
2018-03-05 12:15:17 -08:00
58932c7f38 build(aio): indicate whether properties are read-only in API pages (#22584)
PR Close #22584
2018-03-05 10:15:37 -08:00
5bb9f64218 fixup! feat(aio): allow template to position embedded ToC (#22565)
PR Close #22565
2018-03-05 10:14:16 -08:00
405d97431f fixup! feat(aio): allow template to position embedded ToC (#22565)
PR Close #22565
2018-03-05 10:14:16 -08:00
41064fcb36 fix(aio): reposition and simplify github links (#22565)
Closes #22379

PR Close #22565
2018-03-05 10:14:16 -08:00
b80fd6be58 build(aio): render whether API classes and members are abstract (#22563)
Closes #22537

PR Close #22563
2018-03-05 10:13:43 -08:00
3aea8fd5f3 docs(aio): fix table header (#22553)
PR Close #22553
2018-03-05 10:13:16 -08:00
b64139650c build(aio): class API template once again extends export-base (#22534)
PR Close #22534
2018-03-05 10:12:55 -08:00
1d2bdcb4d0 build(aio): render param descriptions for function exports (#22534)
Closes #22501

PR Close #22534
2018-03-05 10:12:55 -08:00
12be311618 fix(aio): remove all links from toc titles (#22533)
The previous approach just removed the first `a` tag that
was found, but now that the header-link anchor is not at
the start of the heading, it could fail.

Closes #22493

PR Close #22533
2018-03-05 10:12:35 -08:00
51ca643c27 test(ivy): add injectAttribute spec (#22510)
PR Close #22510
2018-03-05 10:10:32 -08:00
69d359bb51 refactor(ivy): break compiler canonical test into smaller files (#22510)
PR Close #22510
2018-03-05 10:10:32 -08:00
4f60968704 test(bazel): Build and test ts-api-guardian locally (#22544)
Also use it to test the public API for core and common

Once we have an ng_package for every package, we can remove
the npm dependency on ts-api-guardian and the gulp-based
public api check.

PR Close #22544
2018-03-02 15:00:00 -08:00
25faf808a5 build: copy ts-api-guardian sources (#22544)
This is an exact mirror of 750f651eca

PR Close #22544
2018-03-02 15:00:00 -08:00
d7e5d45f43 release: packageGroup should use scoped package names (#22538)
PR Close #22538
2018-03-02 14:05:59 -08:00
ba8df8a3f1 build: update to latest bazel rules (#22558)
PR Close #22558
2018-03-02 13:27:25 -08:00
0451fd93df feat(ivy): support generating view and content queries (#22330)
PR Close #22330
2018-03-01 13:06:47 -08:00
49f074f61d feat(ivy): support array and object literals in binding expressions (#22336)
PR Close #22336
2018-03-01 13:02:58 -08:00
ec445b5c73 ci: speed up lint job on CircleCI (#22526)
When I enabled bazel remote caching, I also switched to running
buildifier and skylint from the package.json script, which builds them
from head. With remote caching, we do get cache hits for these, but
looking up the action inputs actually takes quite a bit of time since we
have to first fetch the remote repository, then do loading and
analysis, then read the inputs to determine the cache key.

It's more important to keep the lint job fast, so I'm reverting that
part of the change for now. We can experiment with building them from
head in a less critical repo.

PR Close #22526
2018-03-01 09:12:58 -08:00
ab790f3c84 build: Add support for bazelOptions.maxCacheSizeMb in ngc-wrapped. (#22511)
PR Close #22511
2018-03-01 08:41:10 -08:00
dd534471ec fix(compiler): allow tree-shakeable injectables to depend on string tokens (#22376)
Previously the injectable compiler assumed all tree-shakeable injectables
would have dependencies that were injectables or InjectionTokens. However
old code still uses string tokens (e.g. NgUpgrade and '$injector'). Using
such tokens would cause the injectable compiler to crash.

Now, the injectable compiler can properly generate a dependency on such a
string token.

PR Close #22376
2018-03-01 08:15:13 -08:00
8bb2f5c71d docs(compiler): ivy separate compilation design document (#22480)
PR Close #22480
2018-03-01 08:14:35 -08:00
0e311e3918 build(aio): improve accuracy of code auto-linking (#22494)
The new version of `dgeni-packages/typescript` no longer strips
out "namespaces" from types, which was part of the problem of
not autolinking correctly to `HttpEventType.Response`.

Another part of the problem was that we did not include `.`
characters when matching potential code blocks for auto-linking,
which precluded properties of enums from being linked.

Finally, members we not being given a `path` property, which is
needed to effectively autolink to them. This is now set in
the `simplifyMemberAnchors` processor.

Closes #21375

PR Close #22494
2018-03-01 08:11:19 -08:00
997b30a093 build(aio): move link disambiguation from getLinkInfo to getDocFromAlias (#22494)
The disambiguation needs to be done earlier so that the auto-link-code
post-processor can benefit from it.

PR Close #22494
2018-03-01 08:11:19 -08:00
94707fe795 build(aio): initialise exampleMap correctly (#22502)
The `exampleMap` needs to hold an hash object for each
of the `collectExamples.exampleFolders` paths.

Previously these hash objects were only created if there
was actually an example file the hash's respective
example folder.  This could cause crashes during
`yarn docs-watch` (and so also `yarn sync-and-serve`)
if no examples were read in for a particular run of
the doc-gen.

PR Close #22502
2018-03-01 08:10:15 -08:00
2f0ab7ee98 docs: correct changelog version for 6.0.0-beta.6 2018-03-01 06:05:24 -08:00
b8fe121a16 release: cut the 6.0.0-beta.6 release 2018-02-28 15:23:54 -08:00
669 changed files with 27122 additions and 6660 deletions

View File

@ -15,11 +15,16 @@ build --experimental_remote_spawn_cache --remote_rest_cache=http://localhost:764
# Prevent unstable environment variables from tainting cache keys
build --experimental_strict_action_env
# Save downloaded repositories such as the go toolchain
# This directory can then be included in the CircleCI cache
# It should save time running the first build
build --experimental_repository_cache=/home/circleci/bazel_repository_cache
# Workaround https://github.com/bazelbuild/bazel/issues/3645
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CircleCI "medium" class which is the default:
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class
# https://circleci.com/docs/2.0/configuration-reference/#resource_class
build --local_resources=3072,2.0,1.0
build --local_resources=14336,8.0,1.0
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
test --flaky_test_attempts=2

View File

@ -13,7 +13,7 @@
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.1.0
var_2: &cache_key angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.1.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.1.0
# See remote cache documentation in /docs/BAZEL.md
var_3: &setup-bazel-remote-cache
@ -41,14 +41,14 @@ jobs:
steps:
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- run: 'yarn buildifier -mode=check ||
(echo -e "\nBUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
- run: 'yarn skylint ||
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'buildifier -mode=check $(find . -type f \( -name BUILD.bazel -or -name BUILD \)) ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'find . -type f -name "*.bzl" |
xargs java -jar /usr/local/bin/Skylint_deploy.jar ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
- restore_cache:
@ -59,7 +59,7 @@ jobs:
build:
<<: *job_defaults
resource_class: large
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
@ -71,6 +71,7 @@ jobs:
- restore_cache:
key: *cache_key
- run: ls /home/circleci/bazel_repository_cache || true
- run: bazel info release
- run: bazel run @yarn//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
@ -91,6 +92,7 @@ jobs:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
workflows:
version: 2

View File

@ -26,9 +26,7 @@ merge:
# list of patterns to check for the files changed by the PR
# this list must be manually kept in sync with google3/third_party/javascript/angular2/copy.bara.sky
include:
- "BUILD.bazel"
- "LICENSE"
- "WORKSPACE"
- "modules/**"
- "packages/**"
# list of patterns to ignore for the files changed by the PR
@ -36,6 +34,11 @@ merge:
- "packages/language-service/**"
- "**/.gitignore"
- "**/.gitkeep"
- "**/tsconfig-build.json"
- "**/tsconfig.json"
- "**/rollup.config.js"
- "**/BUILD.bazel"
- "packages/**/test/**"
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.

View File

@ -68,6 +68,7 @@ groups:
- "packages/*"
- "tools/*"
users:
- alexeagle
- IgorMinar
- mhevery

View File

@ -2,8 +2,16 @@ package(default_visibility = ["//visibility:public"])
exports_files([
"tsconfig.json",
"LICENSE",
])
# Developers should always run `bazel run :install`
# This ensures that package.json in subdirectories get installed as well.
alias(
name = "install",
actual = "@yarn//:yarn",
)
# This rule belongs in node_modules/BUILD
# It's here as a workaround for
# https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940
@ -49,6 +57,7 @@ filegroup(
"//:node_modules/zone.js/dist/async-test.js",
"//:node_modules/zone.js/dist/sync-test.js",
"//:node_modules/zone.js/dist/fake-async-test.js",
"//:node_modules/zone.js/dist/task-tracking.js",
"//:node_modules/zone.js/dist/proxy.js",
"//:node_modules/zone.js/dist/jasmine-patch.js",
],

View File

@ -1,5 +1,31 @@
<a name="6.0.0-beta.5"></a>
# [6.0.0-beta.5](https://github.com/angular/angular/compare/6.0.0-beta.4...6.0.0-beta.5) (2018-02-28)
<a name="6.0.0-beta.7"></a>
# [6.0.0-beta.7](https://github.com/angular/angular/compare/6.0.0-beta.6...6.0.0-beta.7) (2018-03-07)
### Bug Fixes
* **bazel:** fixes for ng_package on Windows ([#22597](https://github.com/angular/angular/issues/22597)) ([4c40812](https://github.com/angular/angular/commit/4c40812))
* **compiler:** allow tree-shakeable injectables to depend on string tokens ([#22376](https://github.com/angular/angular/issues/22376)) ([dd53447](https://github.com/angular/angular/commit/dd53447))
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([fa974c7](https://github.com/angular/angular/commit/fa974c7)), closes [#10280](https://github.com/angular/angular/issues/10280)
<a name="5.2.8"></a>
## [5.2.8](https://github.com/angular/angular/compare/5.2.7...5.2.8) (2018-03-07)
### Bug Fixes
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
<a name="6.0.0-beta.6"></a>
# [6.0.0-beta.6](https://github.com/angular/angular/compare/6.0.0-beta.5...6.0.0-beta.6) (2018-02-28)
### Bug Fixes

View File

@ -1,28 +1,25 @@
workspace(name = "angular")
# Using a pre-release snapshot to pick up a commit that makes all nodejs_binary
# programs produce source-mapped stack traces and uglify sourcemaps.
RULES_NODEJS_VERSION = "4303cbef12e5e252ad66cc35cff1123e3a44ee83"
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/%s.zip" % RULES_NODEJS_VERSION,
strip_prefix = "rules_nodejs-%s" % RULES_NODEJS_VERSION,
sha256 = "fccb9a7122f339d89c9994dc0fea33c737dd76e66281d0da0cb841da5f1edec7",
url = "https://github.com/bazelbuild/rules_nodejs/archive/f03c8b5df155da2a640b6775afdd4fe4aa6fec72.zip",
strip_prefix = "rules_nodejs-f03c8b5df155da2a640b6775afdd4fe4aa6fec72",
sha256 = "9d541f49af8cf60c73efb102186bfa5670ee190a088ce52638dcdf90cd9e2de6",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
check_bazel_version("0.9.0")
node_repositories(package_json = ["//:package.json"])
RULES_TYPESCRIPT_VERSION = "d3cc5cd72d89aee0e4c2553ae1b99c707ecbef4e"
node_repositories(package_json = [
"//:package.json",
"//tools/ts-api-guardian:package.json",
])
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/%s.zip" % RULES_TYPESCRIPT_VERSION,
strip_prefix = "rules_typescript-%s" % RULES_TYPESCRIPT_VERSION,
sha256 = "a233fcca41c3e59f639ac71c396edb30e9e9716cf8ed5fb20b51ff8910d5d895",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.11.1.zip",
strip_prefix = "rules_typescript-0.11.1",
sha256 = "7406bea7954e1c906f075115dfa176551a881119f6820b126ea1eacb09f34a1a",
)
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")

View File

@ -1,20 +1,19 @@
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{title}}!!
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular logo" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" href="http://angularjs.blogspot.ca/">Angular blog</a></h2>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>

View File

@ -1,7 +1,5 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
@ -20,13 +18,13 @@ describe('AppComponent', () => {
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app');
expect(app.title).toMatch(/app/i);
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
expect(compiled.querySelector('h1').textContent).toMatch(/app/i);
}));
});

View File

@ -11,6 +11,6 @@ import { Component } from '@angular/core';
// #enddocregion metadata
// #docregion title, class
export class AppComponent {
title = 'My First Angular App';
title = 'My First Angular App!';
}
// #enddocregion title, class

View File

@ -2,7 +2,7 @@
import { Component, Input, OnDestroy } from '@angular/core';
import { MissionService } from './mission.service';
import { Subscription } from 'rxjs/Subscription';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-astronaut',

View File

@ -1,6 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subject } from 'rxjs';
@Injectable()
export class MissionService {

View File

@ -1,6 +1,6 @@
// #docregion
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero, HeroTaxReturn } from './hero';
import { HeroesService } from './heroes.service';

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Observable, Observer } from 'rxjs';
import { Hero, HeroTaxReturn } from './hero';

View File

@ -1,6 +1,6 @@
// #docregion
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Villain, VillainsService } from './villains.service';

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { of } from 'rxjs/observable/of';
import { of } from 'rxjs';
export interface Villain { id: number; name: string; }

View File

@ -28,7 +28,10 @@ let checkLogForMessage = (message: string) => {
expect(page.logList.getText()).toContain(message);
};
describe('Http Tests', function() {
// TODO(i): temorarily disable these tests because angular-in-memory-web-api is not compatible with rxjs v6 yet
// and we don't have the backwards compatibility package yet.
// Reenable after rxjs v6 compatibility package is out or angular-in-memory-web-api is compatible with rxjs v6
xdescribe('Http Tests', function() {
beforeEach(() => {
browser.get('');
});

View File

@ -30,7 +30,7 @@ export class ConfigComponent {
this.configService.getConfig()
// #enddocregion v1, v2
.subscribe(
data => this.config = { ...data }, // success path
(data: Config) => this.config = { ...data }, // success path
error => this.error = error // error path
);
}
@ -39,7 +39,7 @@ export class ConfigComponent {
showConfig_v1() {
this.configService.getConfig_1()
// #docregion v1, v1_callback
.subscribe(data => this.config = {
.subscribe((data: Config) => this.config = {
heroesUrl: data['heroesUrl'],
textfile: data['textfile']
});
@ -51,7 +51,7 @@ export class ConfigComponent {
this.configService.getConfig()
// #docregion v2, v2_callback
// clone the data object, using its known Config shape
.subscribe(data => this.config = { ...data });
.subscribe((data: Config) => this.config = { ...data });
// #enddocregion v2_callback
}
// #enddocregion v2

View File

@ -6,8 +6,7 @@ import { HttpClient } from '@angular/common/http';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
// #docregion rxjs-imports
import { Observable } from 'rxjs/Observable';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
// #enddocregion rxjs-imports
@ -82,8 +81,8 @@ export class ConfigService {
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an ErrorObservable with a user-facing error message
return new ErrorObservable(
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
};
// #enddocregion handleError

View File

@ -6,8 +6,7 @@ import { HttpHeaders } from '@angular/common/http';
// #enddocregion http-options
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Hero } from './hero';

View File

@ -1,8 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { MessageService } from './message.service';

View File

@ -4,8 +4,6 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
// #docregion
import { AuthService } from '../auth.service';

View File

@ -5,8 +5,7 @@ import {
HttpInterceptor, HttpHandler
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { startWith, tap } from 'rxjs/operators';
import { RequestCache } from '../request-cache.service';

View File

@ -3,7 +3,7 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
@Injectable()
export class EnsureHttpsInterceptor implements HttpInterceptor {

View File

@ -4,7 +4,6 @@ import {
HttpRequest, HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
// #docregion excerpt
import { finalize, tap } from 'rxjs/operators';
import { MessageService } from '../message.service';

View File

@ -3,7 +3,7 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
/** Pass untouched request through to the next request handler. */
@Injectable()

View File

@ -3,7 +3,7 @@ import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
@Injectable()
export class TrimNameInterceptor implements HttpInterceptor {

View File

@ -5,8 +5,7 @@ import {
HttpEventType, HttpProgressEvent
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable } from 'rxjs';
/** Simulate server replying to file upload request */
@Injectable()

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
import { NpmPackageInfo, PackageSearchService } from './package-search.service';

View File

@ -1,8 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpErrorHandler, HandleError } from '../http-error-handler.service';

View File

@ -4,7 +4,7 @@ import {
HttpRequest, HttpResponse, HttpErrorResponse
} from '@angular/common/http';
import { of } from 'rxjs/observable/of';
import { of } from 'rxjs';
import { catchError, last, map, tap } from 'rxjs/operators';
import { MessageService } from '../message.service';

View File

@ -2,8 +2,7 @@
// #docregion
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Contact {

View File

@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Crisis,
CrisisService } from './crisis.service';

View File

@ -1,7 +1,6 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Crisis {

View File

@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero,
HeroService } from './hero.service';

View File

@ -1,7 +1,6 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Hero {

View File

@ -1,8 +1,7 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Contact {
constructor(public id: number, public name: string) { }
@ -24,12 +23,12 @@ export class ContactService implements OnDestroy {
ngOnDestroy() { console.log('ContactService instance destroyed.'); }
getContacts(): Observable<Contact[]> {
return delay.call(of(CONTACTS), FETCH_LATENCY);
return of(CONTACTS).pipe(delay(FETCH_LATENCY));
}
getContact(id: number | string): Observable<Contact> {
const contact$ = of(CONTACTS.find(contact => contact.id === +id));
return delay.call(contact$, FETCH_LATENCY);
return contact$.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Customer,
CustomersService } from './customers.service';

View File

@ -1,8 +1,7 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Customer {
constructor(public id: number, public name: string) { }
@ -27,11 +26,11 @@ export class CustomersService implements OnDestroy {
ngOnDestroy() { console.log('CustomersService instance destroyed.'); }
getCustomers(): Observable<Customer[]> {
return delay.call(of(CUSTOMERS), FETCH_LATENCY);
return of(CUSTOMERS).pipe(delay(FETCH_LATENCY));
}
getCustomer(id: number | string): Observable<Customer> {
const customer$ = of(CUSTOMERS.find(customer => customer.id === +id));
return delay.call(customer$, FETCH_LATENCY);
return customer$.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Observable }from 'rxjs/Observable';
import { Observable }from 'rxjs';
import { Item,
ItemService } from './items.service';

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ItemsComponent } from './items.component';
import { ItemsListComponent } from './items-list.component';
import { ItemsDetailComponent } from './items-detail.component';
import { ItemService } from './items.service';
@ -8,7 +9,7 @@ import { ItemsRoutingModule } from './items-routing.module';
@NgModule({
imports: [ CommonModule, ItemsRoutingModule ],
declarations: [ ItemsDetailComponent, ItemsListComponent ],
declarations: [ ItemsComponent, ItemsDetailComponent, ItemsListComponent ],
providers: [ ItemService ]
})
export class ItemsModule {}

View File

@ -1,8 +1,7 @@
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { delay } from 'rxjs/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
export class Item {
constructor(public id: number, public name: string) { }
@ -25,12 +24,12 @@ export class ItemService implements OnDestroy {
ngOnDestroy() { console.log('ItemService instance destroyed.'); }
getItems(): Observable<Item[]> {
return delay.call(of(ITEMS), FETCH_LATENCY);
return of(ITEMS).pipe(delay(FETCH_LATENCY));
}
getItem(id: number | string): Observable<Item> {
const item$ = of(ITEMS.find(item => item.id === +id));
return delay.call(item$, FETCH_LATENCY);
return item$.pipe(delay(FETCH_LATENCY));
}
}

View File

@ -1,6 +1,6 @@
import { Component, Output, OnInit, EventEmitter, NgModule } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
// #docregion eventemitter

View File

@ -1,5 +1,5 @@
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
// #docregion subscriber

View File

@ -1,4 +1,4 @@
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
// #docregion

View File

@ -1,5 +1,5 @@
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
// #docregion delay_sequence

View File

@ -1,6 +1,5 @@
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { Observable, of } from 'rxjs';
// #docregion observer

View File

@ -2,7 +2,7 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular//common/http';
import { AppComponent } from './app.component';
import {
@ -26,7 +26,7 @@ import { ExponentialStrengthPipe } from './exponential-strength.pipe';
imports: [
BrowserModule,
FormsModule,
HttpModule
HttpClientModule
],
declarations: [
AppComponent,

View File

@ -1,9 +1,6 @@
// #docregion
import { Pipe, PipeTransform } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { HttpClient } from '@angular/common/http';
// #docregion pipe-metadata
@Pipe({
name: 'fetch',
@ -14,15 +11,13 @@ export class FetchJsonPipe implements PipeTransform {
private cachedData: any = null;
private cachedUrl = '';
constructor(private http: Http) { }
constructor(private http: HttpClient) { }
transform(url: string): any {
if (url !== this.cachedUrl) {
this.cachedData = null;
this.cachedUrl = url;
this.http.get(url)
.map( result => result.json() )
.subscribe( result => this.cachedData = result );
this.http.get(url).subscribe( result => this.cachedData = result );
}
return this.cachedData;

View File

@ -1,10 +1,8 @@
// #docregion
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { Observable, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';
@Component({
selector: 'app-hero-message',
@ -25,14 +23,17 @@ export class HeroAsyncMessageComponent {
constructor() { this.resend(); }
resend() {
this.message$ = Observable.interval(500)
.map(i => this.messages[i])
.take(this.messages.length);
this.message$ = interval(500).pipe(
map(i => this.messages[i]),
take(this.messages.length)
);
}
}
// #enddocregion
// Alternative message$ formula:
// this.message$ = Observable.fromArray(this.messages)
// .map(message => Observable.timer(500).map(() => message))
// .concatAll();
// this.message$ = fromArray(this.messages).pipe(
// map(message => timer(500),
// map(() => message)),
// concatAll()
// );

View File

@ -1,9 +1,7 @@
import { ajax } from 'rxjs/observable/dom/ajax';
import { range } from 'rxjs/observable/range';
import { timer } from 'rxjs/observable/timer';
import { pipe } from 'rxjs/util/pipe';
import { retryWhen, zip, map, mergeMap } from 'rxjs/operators';
import { pipe, range, timer, zip } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { retryWhen, map, mergeMap } from 'rxjs/operators';
function backoff(maxTries, ms) {
return pipe(

View File

@ -1,6 +1,6 @@
import { fromEvent } from 'rxjs/observable/fromEvent';
import { ajax } from 'rxjs/observable/dom/ajax';
import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { map, filter, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
const searchBox = document.getElementById('search-box');

View File

@ -6,32 +6,38 @@ import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module
import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component'; // <-- #1 import component
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
// #enddocregion v1
// #docregion hero-service-list
// add JavaScript imports
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroService } from './hero.service'; // <-- #1 import service
import { HeroService } from './hero.service';
// #docregion v1
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule // <-- #2 add to @NgModule imports
],
declarations: [
AppComponent,
HeroDetailComponent,
// #enddocregion v1
HeroListComponent
HeroListComponent // <--declare HeroListComponent
// #docregion v1
],
// #enddocregion v1
exports: [ // export for the DemoModule
// #enddocregion hero-service-list
imports: [
BrowserModule,
ReactiveFormsModule // <-- #2 add to @NgModule imports
],
// #enddocregion v1
// export for the DemoModule
// #docregion hero-service-list
// ...
exports: [
AppComponent,
HeroDetailComponent,
HeroListComponent
HeroListComponent // <-- export HeroListComponent
],
providers: [ HeroService ], // <-- #4 provide HeroService
providers: [ HeroService ], // <-- provide HeroService
// #enddocregion hero-service-list
// #docregion v1
bootstrap: [ AppComponent ]
})

View File

@ -1,6 +1,7 @@
/* tslint:disable:member-ordering */
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { Hero } from './data-model';
import { HeroService } from './hero.service';
@ -33,8 +34,9 @@ export class DemoComponent {
getHeroes() {
this.isLoading = true;
this.heroes = this.heroService.getHeroes()
.finally(() => this.isLoading = false);
this.heroes = this.heroService.getHeroes().pipe(
finalize(() => this.isLoading = false)
);
this.selectedHero = undefined;
}

View File

@ -1,7 +1,7 @@
<!-- #docregion basic-form-->
<h2>Hero Detail</h2>
<h3><i>FormControl in a FormGroup</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -1,7 +1,7 @@
<!-- #docregion basic-form-->
<h2>Hero Detail</h2>
<h3><i>A FormGroup with a single FormControl using FormBuilder</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">
@ -13,4 +13,4 @@
<!-- #docregion form-value-json -->
<p>Form value: {{ heroForm.value | json }}</p>
<p>Form status: {{ heroForm.status | json }}</p>
<!-- #enddocregion form-value-json -->
<!-- #enddocregion form-value-json -->

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h2>Hero Detail</h2>
<h3><i>A FormGroup with multiple FormControls</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -1,5 +1,5 @@
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h2>Hero Detail</h2>
<h3><i>PatchValue to initialize a value</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -44,7 +44,13 @@ export class HeroDetailComponent6 implements OnChanges {
}
// #docregion patch-value-on-changes
ngOnChanges() { // <-- wrap patchValue in ngOnChanges
ngOnChanges() { // <-- call rebuildForm in ngOnChanges
this.rebuildForm();
}
// #enddocregion patch-value-on-changes
// #docregion patch-value-rebuildform
rebuildForm() { // <-- wrap patchValue in rebuildForm
this.heroForm.reset();
// #docregion patch-value
this.heroForm.patchValue({
@ -52,7 +58,9 @@ export class HeroDetailComponent6 implements OnChanges {
});
// #enddocregion patch-value
}
// #enddocregion patch-value-on-changes
// #enddocregion patch-value-rebuildform
}
// #enddocregion v6

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h2>Hero Detail</h2>
<h3><i>A FormGroup with multiple FormControls</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">

View File

@ -38,32 +38,31 @@ export class HeroDetailComponent7 implements OnChanges {
// #docregion ngOnChanges
ngOnChanges() {
this.rebuildForm();
}
// #enddocregion ngOnChanges
// #docregion rebuildForm
rebuildForm() {
this.heroForm.reset({
name: this.hero.name,
address: this.hero.addresses[0] || new Address()
});
}
// #enddocregion ngOnChanges
/* First version of ngOnChanges
// #docregion ngOnChanges-1
ngOnChanges()
// #enddocregion ngOnChanges-1
*/
ngOnChanges1() {
// #docregion reset
this.heroForm.reset();
// #enddocregion reset
// #docregion ngOnChanges-1
// #docregion set-value
this.heroForm.setValue({
name: this.hero.name,
// #docregion set-value-address
address: this.hero.addresses[0] || new Address()
// #enddocregion set-value-address
});
}
// #enddocregion rebuildForm
/* First version of rebuildForm */
rebuildForm1() {
// #docregion reset
this.heroForm.reset();
// #enddocregion reset
// #docregion set-value
this.heroForm.setValue({
name: this.hero.name,
address: this.hero.addresses[0] || new Address()
});
// #enddocregion set-value
}
// #enddocregion ngOnChanges-1
}

View File

@ -1,7 +1,7 @@
<!-- #docplaster-->
<h3><i>Using FormArray to add groups</i></h3>
<form [formGroup]="heroForm" novalidate>
<form [formGroup]="heroForm">
<p>Form Changed: {{ heroForm.dirty }}</p>
<div class="form-group">
@ -11,7 +11,9 @@
</div>
<!-- #docregion form-array-->
<!-- #docregion form-array-skeleton -->
<!-- #docregion form-array-name -->
<div formArrayName="secretLairs" class="well well-lg">
<!-- #enddocregion form-array-name -->
<div *ngFor="let address of secretLairs.controls; let i=index" [formGroupName]="i" >
<!-- The repeated address template -->
<!-- #enddocregion form-array-skeleton -->

View File

@ -39,12 +39,18 @@ export class HeroDetailComponent8 implements OnChanges {
// #docregion onchanges
ngOnChanges() {
this.rebuildForm();
}
// #enddocregion onchanges
// #docregion rebuildform
rebuildForm() {
this.heroForm.reset({
name: this.hero.name
});
this.setAddresses(this.hero.addresses);
}
// #enddocregion onchanges
// #enddocregion rebuildform
// #docregion get-secret-lairs
get secretLairs(): FormArray {

View File

@ -1,11 +1,11 @@
<!-- #docplaster -->
<!-- #docregion -->
<!-- #docregion buttons -->
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()" novalidate>
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()">
<div style="margin-bottom: 1em">
<button type="submit"
[disabled]="heroForm.pristine" class="btn btn-success">Save</button> &nbsp;
<button type="reset" (click)="revert()"
<button type="button" (click)="revert()"
[disabled]="heroForm.pristine" class="btn btn-danger">Revert</button>
</div>

View File

@ -13,7 +13,10 @@ import { HeroService } from '../hero.service';
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css']
})
// #docregion onchanges-implementation
export class HeroDetailComponent implements OnChanges {
// #enddocregion onchanges-implementation
@Input() hero: Hero;
heroForm: FormGroup;
@ -42,6 +45,10 @@ export class HeroDetailComponent implements OnChanges {
}
ngOnChanges() {
this.rebuildForm();
}
rebuildForm() {
this.heroForm.reset({
name: this.hero.name
});
@ -66,7 +73,7 @@ export class HeroDetailComponent implements OnChanges {
onSubmit() {
this.hero = this.prepareSaveHero();
this.heroService.updateHero(this.hero).subscribe(/* error handling */);
this.ngOnChanges();
this.rebuildForm();
}
// #enddocregion on-submit
@ -92,7 +99,7 @@ export class HeroDetailComponent implements OnChanges {
// #enddocregion prepare-save-hero
// #docregion revert
revert() { this.ngOnChanges(); }
revert() { this.rebuildForm(); }
// #enddocregion revert
// #docregion log-name-change

View File

@ -1,7 +1,7 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/finally';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { Hero } from '../data-model';
import { HeroService } from '../hero.service';
@ -24,7 +24,7 @@ export class HeroListComponent implements OnInit {
this.isLoading = true;
this.heroes = this.heroService.getHeroes()
// Todo: error handling
.finally(() => this.isLoading = false);
.pipe(finalize(() => this.isLoading = false));
this.selectedHero = undefined;
}

View File

@ -1,9 +1,8 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/delay';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { Hero, heroes } from './data-model';
@ -14,13 +13,13 @@ export class HeroService {
// Fake server get; assume nothing can go wrong
getHeroes(): Observable<Hero[]> {
return of(heroes).delay(this.delayMs); // simulate latency with delay
return of(heroes).pipe(delay(this.delayMs)); // simulate latency with delay
}
// Fake server update; assume nothing can go wrong
updateHero(hero: Hero): Observable<Hero> {
const oldHero = heroes.find(h => h.id === hero.id);
const newHero = Object.assign(oldHero, hero); // Demo: mutate cached hero
return of(newHero).delay(this.delayMs); // simulate latency with delay
return of(newHero).pipe(delay(this.delayMs)); // simulate latency with delay
}
}

View File

@ -1,8 +1,8 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
template: `
@ -23,11 +23,11 @@ export class AdminDashboardComponent implements OnInit {
// Capture the session ID if available
this.sessionId = this.route
.queryParamMap
.map(params => params.get('session_id') || 'None');
.pipe(map(params => params.get('session_id') || 'None'));
// Capture the fragment if available
this.token = this.route
.fragment
.map(fragment => fragment || 'None');
.pipe(map(fragment => fragment || 'None'));
}
}

View File

@ -1,11 +1,11 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SelectivePreloadingStrategy } from '../selective-preloading-strategy';
import 'rxjs/add/operator/map';
@Component({
template: `
@ -37,11 +37,11 @@ export class AdminDashboardComponent implements OnInit {
// Capture the session ID if available
this.sessionId = this.route
.queryParamMap
.map(params => params.get('session_id') || 'None');
.pipe(map(params => params.get('session_id') || 'None'));
// Capture the fragment if available
this.token = this.route
.fragment
.map(fragment => fragment || 'None');
.pipe(map(fragment => fragment || 'None'));
}
}

View File

@ -1,8 +1,8 @@
// #docregion
import { animate, AnimationEntryMetadata, state, style, transition, trigger } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
// Component transition animations
export const slideInDownAnimation: AnimationEntryMetadata =
export const slideInDownAnimation =
trigger('routeAnimation', [
state('*',
style({

View File

@ -1,10 +1,8 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/delay';
import { Observable, of } from 'rxjs';
import { tap, delay } from 'rxjs/operators';
@Injectable()
export class AuthService {
@ -14,7 +12,10 @@ export class AuthService {
redirectUrl: string;
login(): Observable<boolean> {
return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
return of(true).pipe(
delay(1000),
tap(val => this.isLoggedIn = true)
);
}
logout(): void {

View File

@ -1,6 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';

View File

@ -1,7 +1,7 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;

View File

@ -1,10 +1,9 @@
// #docregion
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { Crisis, CrisisService } from './crisis.service';
@ -15,13 +14,16 @@ export class CrisisDetailResolver implements Resolve<Crisis> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> {
let id = route.paramMap.get('id');
return this.cs.getCrisis(id).take(1).map(crisis => {
if (crisis) {
return crisis;
} else { // id not found
this.router.navigate(['/crisis-center']);
return null;
}
});
return this.cs.getCrisis(id).pipe(
take(1),
map(crisis => {
if (crisis) {
return crisis;
} else { // id not found
this.router.navigate(['/crisis-center']);
return null;
}
})
);
}
}

View File

@ -1,9 +1,9 @@
// #docplaster
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { slideInDownAnimation } from '../animations';
import { Crisis, CrisisService } from './crisis.service';
@ -46,8 +46,9 @@ export class CrisisDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getCrisis(params.get('id')))
.pipe(
switchMap((params: ParamMap) =>
this.service.getCrisis(params.get('id'))))
.subscribe((crisis: Crisis) => {
if (crisis) {
this.editName = crisis.name;

View File

@ -2,7 +2,7 @@
// #docregion
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { slideInDownAnimation } from '../animations';
import { Crisis } from './crisis.service';

View File

@ -1,10 +1,10 @@
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
// #docregion relative-navigation-router-link
@ -34,10 +34,11 @@ export class CrisisListComponent implements OnInit {
ngOnInit() {
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.crises$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
})
);
}
}

View File

@ -1,10 +1,10 @@
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
template: `
@ -32,10 +32,11 @@ export class CrisisListComponent implements OnInit {
// #enddocregion ctor
ngOnInit() {
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.crises$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
})
);
}
}

View File

@ -1,8 +1,7 @@
// #docplaster
// #docregion , mock-crises
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
export class Crisis {
constructor(public id: number, public name: string) { }
@ -26,8 +25,9 @@ export class CrisisService {
getCrises() { return this.crises$; }
getCrisis(id: number | string) {
return this.getCrises()
.map(crises => crises.find(crisis => crisis.id === +id));
return this.getCrises().pipe(
map(crises => crises.find(crisis => crisis.id === +id))
);
}
// #enddocregion

View File

@ -1,7 +1,6 @@
// #docregion
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable, of } from 'rxjs';
/**
* Async modal dialog service
@ -17,6 +16,6 @@ export class DialogService {
confirm(message?: string): Observable<boolean> {
const confirmation = window.confirm(message || 'Is it OK?');
return Observable.of(confirmation);
return of(confirmation);
};
}

View File

@ -1,10 +1,10 @@
// #docplaster
// #docregion
// #docregion rxjs-operator-import
import 'rxjs/add/operator/switchMap';
import { switchMap } from 'rxjs/operators';
// #enddocregion rxjs-operator-import
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
// #docregion imports
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
// #enddocregion imports
@ -41,9 +41,10 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')));
this.hero$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
);
}
// #enddocregion ngOnInit

View File

@ -2,7 +2,7 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero, HeroService } from './hero.service';

View File

@ -1,11 +1,11 @@
// #docplaster
// #docregion
// #docregion rxjs-operator-import
import 'rxjs/add/operator/switchMap';
import { switchMap } from 'rxjs/operators';
// #enddocregion rxjs-operator-import
import { Component, OnInit, HostBinding } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';
import { slideInDownAnimation } from '../animations';
@ -48,9 +48,10 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')));
this.hero$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
);
}
// #enddocregion ngOnInit

View File

@ -3,7 +3,7 @@
// TODO SOMEDAY: Feature Componetized like HeroCenter
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { Hero, HeroService } from './hero.service';

View File

@ -2,8 +2,8 @@
// #docregion
// TODO SOMEDAY: Feature Componetized like CrisisCenter
// #docregion rxjs-imports
import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
// #enddocregion rxjs-imports
import { Component, OnInit } from '@angular/core';
// #docregion import-router
@ -41,12 +41,13 @@ export class HeroListComponent implements OnInit {
) {}
ngOnInit() {
this.heroes$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.heroes$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
// (+) before `params.get()` turns the string into a number
this.selectedId = +params.get('id');
return this.service.getHeroes();
});
})
);
}
// #enddocregion ctor
// #docregion ctor

View File

@ -1,8 +1,7 @@
// #docregion
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
export class Hero {
constructor(public id: number, public name: string) { }
@ -19,11 +18,12 @@ const HEROES = [
@Injectable()
export class HeroService {
getHeroes() { return Observable.of(HEROES); }
getHeroes() { return of(HEROES); }
getHero(id: number | string) {
return this.getHeroes()
return this.getHeroes().pipe(
// (+) before `id` turns the string into a number
.map(heroes => heroes.find(hero => hero.id === +id));
map(heroes => heroes.find(hero => hero.id === +id))
);
}
}

View File

@ -1,8 +1,7 @@
// #docregion
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Observable, of } from 'rxjs';
@Injectable()
export class SelectivePreloadingStrategy implements PreloadingStrategy {
@ -18,7 +17,7 @@ export class SelectivePreloadingStrategy implements PreloadingStrategy {
return load();
} else {
return Observable.of(null);
return of(null);
}
}
}

View File

@ -1,10 +1,9 @@
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { of } from 'rxjs';
// #docregion
import { ajax } from 'rxjs/observable/dom/ajax';
import { ajax } from 'rxjs/ajax';
import { map, catchError } from 'rxjs/operators';
// Return "response" from the API. If an error happens,
// return an empty array.
@ -15,7 +14,7 @@ const apiData = ajax('/api/data').pipe(
}
return res.response;
}),
catchError(err => Observable.of([]))
catchError(err => of([]))
);
apiData.subscribe({

View File

@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs';
@Component({
selector: 'app-stopwatch',

View File

@ -1,12 +1,10 @@
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { of, pipe } from 'rxjs';
// #docregion
import { pipe } from 'rxjs/util/pipe';
import { filter, map } from 'rxjs/operators';
const nums = Observable.of(1, 2, 3, 4, 5);
const nums = of(1, 2, 3, 4, 5);
// Create a function that accepts an Observable.
const squareOddVals = pipe(

View File

@ -1,12 +1,10 @@
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { Observable, of } from 'rxjs';
// #docregion
import { filter } from 'rxjs/operators/filter';
import { map } from 'rxjs/operators/map';
import { filter, map } from 'rxjs/operators';
const squareOdd = Observable.of(1, 2, 3, 4, 5)
const squareOdd = of(1, 2, 3, 4, 5)
.pipe(
filter(n => n % 2),
map(n => n * n)

View File

@ -1,12 +1,11 @@
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { Observable, of } from 'rxjs';
// #docregion
import { map } from 'rxjs/operators';
const nums = Observable.of(1, 2, 3);
const nums = of(1, 2, 3);
const squareValues = map((val: number) => val * val);
const squaredNums = squareValues(nums);

View File

@ -1,11 +1,10 @@
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { Observable, of } from 'rxjs';
// #docregion
import { ajax } from 'rxjs/observable/dom/ajax';
import { ajax } from 'rxjs/ajax';
import { map, retry, catchError } from 'rxjs/operators';
const apiData = ajax('/api/data').pipe(
@ -16,7 +15,7 @@ const apiData = ajax('/api/data').pipe(
}
return res.response;
}),
catchError(err => Observable.of([]))
catchError(err => of([]))
);
apiData.subscribe({

View File

@ -1,7 +1,7 @@
// #docregion promise
import { fromPromise } from 'rxjs/observable/fromPromise';
import { fromPromise } from 'rxjs';
// Create an Observable out of a promise
const data = fromPromise(fetch('/api/endpoint'));
@ -16,7 +16,7 @@ data.subscribe({
// #docregion interval
import { interval } from 'rxjs/observable/interval';
import { interval } from 'rxjs';
// Create an Observable that will publish a value on an interval
const secondsCounter = interval(1000);
@ -29,7 +29,7 @@ secondsCounter.subscribe(n =>
// #docregion event
import { fromEvent } from 'rxjs/observable/fromEvent';
import { fromEvent } from 'rxjs';
const el = document.getElementById('my-element');
@ -53,7 +53,7 @@ const subscription = mouseMoves.subscribe((evt: MouseEvent) => {
// #docregion ajax
import { ajax } from 'rxjs/observable/dom/ajax';
import { ajax } from 'rxjs/ajax';
// Create an Observable that will create an AJAX request
const apiData = ajax('/api/data');

View File

@ -3,7 +3,7 @@ import { SwUpdate } from '@angular/service-worker';
// #docregion sw-check-update
import { interval } from 'rxjs/observable/interval';
import { interval } from 'rxjs';
@Injectable()
export class CheckForUpdateService {

View File

@ -5,6 +5,7 @@
import { ExceptionService, SpinnerService, ToastService } from '../../core';
import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { Hero } from './hero.model';
// #enddocregion example
@ -19,13 +20,13 @@ export class HeroService {
) { }
getHero(id: number) {
return this.http.get(`api/heroes/${id}`)
.map(response => response.json().data as Hero);
return this.http.get(`api/heroes/${id}`).pipe(
map(response => response.json().data as Hero));
}
getHeroes() {
return this.http.get(`api/heroes`)
.map(response => response.json().data as Hero[]);
return this.http.get(`api/heroes`).pipe(
map(response => response.json().data as Hero[]));
}
}

View File

@ -2,6 +2,7 @@
// #docregion example
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { map } from 'rxjs/operators';
import { Hero } from './hero.model';
import { ExceptionService, SpinnerService, ToastService } from '../../core';
@ -19,13 +20,13 @@ export class HeroService {
) { }
getHero(id: number) {
return this.http.get(`api/heroes/${id}`)
.map(response => response.json() as Hero);
return this.http.get(`api/heroes/${id}`).pipe(
map(response => response.json() as Hero));
}
getHeroes() {
return this.http.get(`api/heroes`)
.map(response => response.json() as Hero[]);
return this.http.get(`api/heroes`).pipe(
map(response => response.json() as Hero[]));
}
}

View File

@ -1,6 +1,6 @@
// #docregion
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { Subscription } from 'rxjs';
import { LoggerService } from '../logger.service';
import { SpinnerState, SpinnerService } from './spinner.service';

View File

@ -1,6 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subject } from 'rxjs';
export interface SpinnerState {
show: boolean;

Some files were not shown because too many files have changed in this diff Show More