Commit Graph

24 Commits

Author SHA1 Message Date
Matthieu Riegler 1c63eddb7c refactor(router): remouve unused (#53750)
minor optimisation, removing unused paramters.

PR Close #53750
2024-01-03 13:29:05 -08:00
Charles Lyding e149ebf228 build: update rxjs build version to v7 (#53500)
The version of rxjs used to build the repository has been updated to v7.
This required only minimal changes to the code. Most of which were type
related only due to more strict types in v7. The behavior in those cases
was left intact. The most common type related change was to handle the
possibility of `undefined` with `toPromise` which was always possible with
v6 but the types did not reflect the runtime behavior. The one change that
was not type related was to provide a parameter value to the `defaultIfEmpty`
operator. It no longer defaults to a value of `null` if no default is provided.
To provide the same behavior the value of `null` is now passed to the operator.

PR Close #53500
2023-12-18 16:25:37 +00:00
Andrew Scott 3c7e637374 fix(router): Route matching should only happen once when navigating (#49163)
When navigating in the Router, the current approach does the redirects
and the creation of the `RouterStateSnapshot` in two separate steps
(applyRedirects and recognize). These two steps duplicate the route
matching logic, resulting in user code on routes being executing twice
(custom `UrlMatcher` and `canMatch` guards). This also duplicates the
complex matching logic in two places, which increases the bundle size
and maintenance burden.

This commit combines the `applyRedirects` and `recognize` steps into a
single matching algorithm.

fixes #26081

PR Close #49163
2023-03-29 14:40:41 -07:00
Andrew Scott 0432d952a1 Revert "fix(router): Route matching should only happen once when navigating (#49163)" (#49634)
This reverts commit 1600687fe5.

PR Close #49634
2023-03-29 11:37:29 -07:00
Andrew Scott 1600687fe5 fix(router): Route matching should only happen once when navigating (#49163)
When navigating in the Router, the current approach does the redirects
and the creation of the `RouterStateSnapshot` in two separate steps
(applyRedirects and recognize). These two steps duplicate the route
matching logic, resulting in user code on routes being executing twice
(custom `UrlMatcher` and `canMatch` guards). This also duplicates the
complex matching logic in two places, which increases the bundle size
and maintenance burden.

This commit combines the `applyRedirects` and `recognize` steps into a
single matching algorithm.

fixes #26081

PR Close #49163
2023-03-28 13:53:57 -07:00
Andrew Scott de058bba99 feat(router): Add CanMatch guard to control whether a Route should match (#46021)
Currently we have two main types of guards:
`CanLoad`: decides if we can load a module (used with lazy loading)
`CanActivate` and friends. It decides if we can activate/deactivate a route.
So we always decide where we want to navigate first ("recognize") and create a new router state snapshot. And only then we run guards to check if the navigation should be allowed.
This doesn't handle one very important use case where we want to decide where to navigate based on some data (e.g., who the user is).
I suggest to add a new guard that allows us to do that.

```
[
  {path: 'home', component: AdminHomePage, canUse: [IsAdmin]},
  {path: 'home', component: SimpleHomePage}
]
```

Here, navigating to '/home' will render `AdminHomePage` if the user is an admin and will render 'SimpleHomePage' otherwise. Note that the url will remain '/home'.

With the introduction of standalone components and new features in the Router such as `loadComponent`,
there's a case for deprecating `CanLoad` and replacing it with the `CanMatch` guard. There are a few reasons for this:

* One of the intentions of having separate providers on a Route is that lazy
loading should not be an architectural feature of an application. It's an
optimization you do for code size. That is, there should not be an architectural
feature in the router to specifically control whether to lazy load something or
not based on conditions such as authentication. This is a slight nuanced
difference between the proposed canUse guard: this guard would control whether
you can use the route at all and as a side-effect, whether we download the code.
`CanLoad` only specified whether the code should be downloaded so canUse is more powerful and more appropriate.
* The naming of `CanLoad` will be potentially misunderstood for the `loadComponent` feature.
Because it applies to `loadChildren`, it feels reasonable to think that it will
also apply to `loadComponent`. This isn’t the case: since we don't need
to load the component until right before activation, we defer the
loading until all guards/resolvers have run.

When considering the removal of `CanLoad` and replacing it with `CanMatch`, this
does inform another decision that needed to be made: whether it makes sense for
`CanMatch` guards to return a UrlTree or if they should be restricted to just boolean.
The original thought was that no, these new guards should not allow returning UrlTree
because that significantly expands the intent of the feature from simply
“can I use the route” to “can I use this route, and if not, should I redirect?”
I now believe it should allowed to return `UrlTree` for several reasons:

* For feature parity with `CanLoad`
* Because whether we allow it as a return value or not, developers will still be
able to trigger a redirect from the guards using the `Router.navigate` function.
* Inevitably, there will be developers who disagree with the philosophical decision
to disallow `UrlTree` and we don’t necessarily have a compelling reason to refuse this as a feature.

Relates to #16211 - `CanMatch` instead of `CanActivate` would prevent
blank screen. Additional work is required to close this issue. This can
be accomplished by making the initial navigation result trackable (including
the redirects).
Resolves #14515
Replaces #16416
Resolves #34231
Resolves #17145
Resolves #12088

PR Close #46021
2022-06-13 22:53:49 +00:00
Andrew Scott 7fd416d060 fix(router): Fix type of Route.pathMatch to be more accurate (#45176)
Route.pathMatch only allows `'full'|'prefix'` in reality. This commit
adjusts the type to be more strict and also adds a migration to adjust
existing code.

resolves #37469

BREAKING CHANGE:
The type of `Route.pathMatch` is now more strict. Places that use
`pathMatch` will likely need to be updated to have an explicit
`Route`/`Routes` type so that TypeScript does not infer the type as
`string`.

PR Close #45176
2022-02-24 18:44:07 +00:00
markostanimirovic 4dbd2028fe refactor(router): move types from config and interfaces to models (#44939)
This commit moves all types from `config.ts` and `interfaces.ts`
to `models.ts` to fix circular dependency.

PR Close #44939
2022-02-03 12:40:28 -08:00
Dmitrij Kuba 6bceb709df fix(router): Only retrieve stored route when reuse strategy indicates it should reattach (#30263)
When creating the router state, the `RouteReuseStrategy#retrieve` should
only be called when `RouteReuseStrategy#shouldAttach` returns `true`.
That is, we should only retrieve a stored route when the reuse strategy
indicates that there is one stored and that it should be reattached.

This now matches the behavior in the route activation:
https://github.com/angular/angular/blob/1d12c50f63f90c91636185b2287e31e9c0291121/packages/router/src/operators/activate_routes.ts#L170-L172

Fixes #23162

PR Close #30263
2021-04-15 11:32:59 -07:00
Mathieu Lemoine 3817e5f1df fix(router): Fix arguments order for call to shouldReuseRoute (#26949)
The `createOrReuseChildren` function calls shouldReuseRoute with the
previous child values use as the future and the future child value used
as the current argument. This is incosistent with the argument order in
`createNode`. This inconsistent order can make it difficult/impossible
to correctly implement the `shouldReuseRoute` function. Usually this
order doesn't matter because simple equality checks are made on the
args and it doesn't matter which is which.

More detail can be found in the bug report: #16192.

Fix #16192

BREAKING CHANGE: This change corrects the argument order when calling
RouteReuseStrategy#shouldReuseRoute. Previously, when evaluating child
routes, they would be called with the future and current arguments would
be swapped. If your RouteReuseStrategy relies specifically on only the future
or current snapshot state, you may need to update the shouldReuseRoute
implementation's use of "future" and "current" ActivateRouteSnapshots.

PR Close #26949
2020-09-15 11:33:52 -07:00
Joey Perrott d1ea1f4c7f build: update license headers to reference Google LLC (#37205)
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
Joey Perrott 698b0288be build: reformat repo to new clang@1.4.0 (#36613)
PR Close #36613
2020-04-14 12:08:36 -07:00
George Kalpakas 00c110b055 build: upgrade jasmine (and related typings) to latest version (#19904)
With these changes, the types are a little stricter now and also not
compatible with Protractor's jasmine-like syntax. So, we have to also
use `@types/jasminewd2` for e2e tests (but not for non-e2e tests).

I also had to "augment" `@types/jasminewd2`, because the latest
typings from [DefinitelyTyped][1] do not reflect the fact that the
`jasminewd2` version (v2.1.0) currently used by Protractor supports
passing a `done` callback to a spec.

[1]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/566e0394859fdc1dc893658ccec6b06372d56a91/types/jasminewd2/index.d.ts#L9-L15

Fixes #23952
Closes #24733

PR Close #19904
2018-07-06 13:48:02 -07:00
Steven Liekens 4cfa571258 fix(router): cache route handle if found (#22475)
When asking the route reuse strategy to retrieve a detached route handle, store the
return value in a local variable for further processing instead of asking again later.

resolves #22474

PR Close #22475
2018-04-23 13:35:59 -07:00
Steven Liekens d37064ce28 test(router): fix typo in expectation (#23137)
PR Close #23137
2018-04-04 08:22:03 -07:00
Misko Hevery 3d50fd7cac build: add bazel test rules for remainder of packages (#21053)
PR Close #21053
2017-12-22 13:10:51 -08:00
Victor Berchet 81ca51a8f0 refactor(router): cleanup, simplification 2017-05-19 11:55:15 -07:00
Matias Niemelä 86b7bd9c8e revert: refactor(router): cleanup, simplification
This reverts commit 44d48d9d7a.
2017-05-18 11:57:22 -07:00
Victor Berchet 44d48d9d7a refactor(router): cleanup, simplification 2017-05-17 19:32:04 -07:00
Miško Hevery bc431888f3 fix(router): Update types for TypeScript nullability support
This reverts commit ea8ffc9841.
2017-04-18 12:07:33 -07:00
Tobias Bosch ea8ffc9841 Revert "fix(router): Update types for TypeScript nullability support"
This reverts commit 56c46d70f7.

Broke in G3.
2017-04-17 09:56:09 -07:00
Miško Hevery 56c46d70f7 fix(router): Update types for TypeScript nullability support 2017-04-14 14:31:17 -07:00
Victor Berchet a755b715ed feat(router): introduce ParamMap to access parameters
The Router use the type `Params` for all of:
- position parameters,
- matrix parameters,
- query parameters.

`Params` is defined as follow `type Params = {[key: string]: any}`

Because parameters can either have single or multiple values, the type should
actually be `type Params = {[key: string]: string | string[]}`.

The client code often assumes that parameters have single values, as in the
following exemple:

```
class MyComponent {
sessionId: Observable<string>;

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    this.sessionId = this.route
      .queryParams
      .map(params => params['session_id'] || 'None');
}
}

```

The problem here is that `params['session_id']` could be `string` or `string[]`
but the error is not caught at build time because of the `any` type.

Fixing the type as describe above would break the build because `sessionId`
would becomes an `Observable<string | string[]>`.

However the client code knows if it expects a single or multiple values. By
using the new `ParamMap` interface the user code can decide when it needs a
single value (calling `ParamMap.get(): string`) or multiple values (calling
`ParamMap.getAll(): string[]`).

The above exemple should be rewritten as:

```
class MyComponent {
sessionId: Observable<string>;

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    this.sessionId = this.route
      .queryParamMap
      .map(paramMap => paramMap.get('session_id') || 'None');
}
}

```

Added APIs:
- `interface ParamMap`,
- `ActivatedRoute.paramMap: ParamMap`,
- `ActivatedRoute.queryParamMap: ParamMap`,
- `ActivatedRouteSnapshot.paramMap: ParamMap`,
- `ActivatedRouteSnapshot.queryParamMap: ParamMap`,
- `UrlSegment.parameterMap: ParamMap`
2017-03-20 09:19:32 -07:00
Jason Aden 3e51a19983 refactor: move angular source to /packages rather than modules/@angular 2017-03-08 16:29:27 -08:00