Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions aio/content/guide/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ v15 - v18
| `@angular/router` | [`RouterLinkWithHref` directive](#router) | v15 | v17 |
| `@angular/router` | [Router writeable properties](#router-writable-properties) | v15.1 | v17 |
| `@angular/router` | [Router CanLoad guards](#router-can-load) | v15.1 | v17 |
| `@angular/router` | [class and `InjectionToken` guards and resolvers](#router) | v15.2 | v17 |

### Deprecated features with no planned removal version

Expand Down Expand Up @@ -203,6 +204,8 @@ In the [API reference section](api) of this site, deprecated APIs are indicated
| [`RouterLinkWithHref` directive](api/router/RouterLinkWithHref) | Use `RouterLink` instead. | v15 | The `RouterLinkWithHref` directive code was merged into `RouterLink`. Now the `RouterLink` directive can be used for all elements that have `routerLink` attribute. |
| [`provideRoutes` function](api/router/provideRoutes) | Use `ROUTES` `InjectionToken` instead. | v15 | The `provideRoutes` helper function is minimally useful and can be unintentionally used instead of `provideRouter` due to similar spelling. |
| [`setupTestingRouter` function](api/router/testing/setupTestingRouter) | Use `provideRouter` or `RouterTestingModule` instead. | v15.1 | The `setupTestingRouter` function is not necessary. The `Router` is initialized based on the DI configuration in tests as it would be in production. |
| [class and `InjectionToken` guards and resolvers](api/router/DeprecatedGuard) | Use plain JavaScript functions instead. | v15.2 | Functional guards are simpler and more powerful than class and token-based guards. |


<a id="platform-browser"></a>

Expand Down
26 changes: 15 additions & 11 deletions goldens/public-api/router/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { OnChanges } from '@angular/core';
import { OnDestroy } from '@angular/core';
import { OnInit } from '@angular/core';
import { Provider } from '@angular/core';
import { ProviderToken } from '@angular/core';
import { QueryList } from '@angular/core';
import { Renderer2 } from '@angular/core';
import { SimpleChanges } from '@angular/core';
Expand Down Expand Up @@ -111,13 +112,13 @@ export abstract class BaseRouteReuseStrategy implements RouteReuseStrategy {
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void;
}

// @public
// @public @deprecated
export interface CanActivate {
// (undocumented)
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
}

// @public
// @public @deprecated
export interface CanActivateChild {
// (undocumented)
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
Expand All @@ -129,7 +130,7 @@ export type CanActivateChildFn = (childRoute: ActivatedRouteSnapshot, state: Rou
// @public
export type CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;

// @public
// @public @deprecated
export interface CanDeactivate<T> {
// (undocumented)
canDeactivate(component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
Expand All @@ -147,7 +148,7 @@ export interface CanLoad {
// @public @deprecated
export type CanLoadFn = (route: Route, segments: UrlSegment[]) => Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;

// @public
// @public @deprecated
export interface CanMatch {
// (undocumented)
canMatch(route: Route, segments: UrlSegment[]): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
Expand Down Expand Up @@ -237,6 +238,9 @@ export class DefaultUrlSerializer implements UrlSerializer {
serialize(tree: UrlTree): string;
}

// @public @deprecated
export type DeprecatedGuard = ProviderToken<any> | any;

// @public
export type DetachedRouteHandle = {};

Expand Down Expand Up @@ -561,15 +565,15 @@ export function provideRoutes(routes: Routes): Provider[];
// @public
export type QueryParamsHandling = 'merge' | 'preserve' | '';

// @public
// @public @deprecated
export interface Resolve<T> {
// (undocumented)
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T;
}

// @public
export type ResolveData = {
[key: string | symbol]: any | ResolveFn<unknown>;
[key: string | symbol]: ResolveFn<unknown> | DeprecatedGuard;
};

// @public
Expand Down Expand Up @@ -611,12 +615,12 @@ export class ResolveStart extends RouterEvent {

// @public
export interface Route {
canActivate?: Array<CanActivateFn | any>;
canActivateChild?: Array<CanActivateChildFn | any>;
canDeactivate?: Array<CanDeactivateFn<any> | any>;
canActivate?: Array<CanActivateFn | DeprecatedGuard>;
canActivateChild?: Array<CanActivateChildFn | DeprecatedGuard>;
canDeactivate?: Array<CanDeactivateFn<any> | DeprecatedGuard>;
// @deprecated
canLoad?: Array<CanLoadFn | any>;
canMatch?: Array<Type<CanMatch> | InjectionToken<CanMatchFn> | CanMatchFn>;
canLoad?: Array<CanLoadFn | DeprecatedGuard>;
canMatch?: Array<CanMatchFn | DeprecatedGuard>;
children?: Routes;
component?: Type<any>;
data?: Data;
Expand Down
2 changes: 1 addition & 1 deletion packages/router/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export {RouterLink, RouterLinkWithHref} from './directives/router_link';
export {RouterLinkActive} from './directives/router_link_active';
export {RouterOutlet, RouterOutletContract} from './directives/router_outlet';
export {ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, Event, EventType, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationCancellationCode as NavigationCancellationCode, NavigationEnd, NavigationError, NavigationSkipped, NavigationSkippedCode, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, Scroll} from './events';
export {CanActivate, CanActivateChild, CanActivateChildFn, CanActivateFn, CanDeactivate, CanDeactivateFn, CanLoad, CanLoadFn, CanMatch, CanMatchFn, Data, DefaultExport, LoadChildren, LoadChildrenCallback, NavigationBehaviorOptions, OnSameUrlNavigation, QueryParamsHandling, Resolve, ResolveData, ResolveFn, Route, Routes, RunGuardsAndResolvers, UrlMatcher, UrlMatchResult} from './models';
export {CanActivate, CanActivateChild, CanActivateChildFn, CanActivateFn, CanDeactivate, CanDeactivateFn, CanLoad, CanLoadFn, CanMatch, CanMatchFn, Data, DefaultExport, DeprecatedGuard, LoadChildren, LoadChildrenCallback, NavigationBehaviorOptions, OnSameUrlNavigation, QueryParamsHandling, Resolve, ResolveData, ResolveFn, Route, Routes, RunGuardsAndResolvers, UrlMatcher, UrlMatchResult} from './models';
export {Navigation, NavigationExtras, UrlCreationOptions} from './navigation_transition';
export {DefaultTitleStrategy, TitleStrategy} from './page_title_strategy';
export {DebugTracingFeature, DisabledInitialNavigationFeature, EnabledBlockingInitialNavigationFeature, InitialNavigationFeature, InMemoryScrollingFeature, NavigationErrorHandlerFeature, PreloadingFeature, provideRouter, provideRoutes, RouterConfigurationFeature, RouterFeature, RouterFeatures, RouterHashLocationFeature, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withHashLocation, withInMemoryScrolling, withNavigationErrorHandler, withPreloading, withRouterConfig} from './provide_router';
Expand Down
43 changes: 35 additions & 8 deletions packages/router/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {EnvironmentInjector, EnvironmentProviders, InjectionToken, NgModuleFactory, Provider, Type} from '@angular/core';
import {EnvironmentInjector, EnvironmentProviders, NgModuleFactory, Provider, ProviderToken, Type} from '@angular/core';
import {Observable} from 'rxjs';

import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state';
Expand Down Expand Up @@ -38,6 +38,23 @@ import {UrlSegment, UrlSegmentGroup, UrlTree} from './url_tree';
*/
export type OnSameUrlNavigation = 'reload'|'ignore';

/**
* The `InjectionToken` and `@Injectable` classes for guards and resolvers are deprecated in favor
* of plain JavaScript functions instead.. Dependency injection can still be achieved using the
* `inject` function from `@angular/core`.
*
* @deprecated
* @see CanMatchFn
* @see CanLoadFn
* @see CanActivateFn
* @see CanActivateChildFn
* @see CanDeactivateFn
* @see ResolveFn
* @see inject
* @publicApi
*/
export type DeprecatedGuard = ProviderToken<any>|any;

/**
* Represents a route configuration for the Router service.
* An array of `Route` objects, used in `Router.config` and for nested route configurations
Expand Down Expand Up @@ -110,7 +127,7 @@ export type Data = {
* @publicApi
*/
export type ResolveData = {
[key: string|symbol]: any|ResolveFn<unknown>
[key: string|symbol]: ResolveFn<unknown>|DeprecatedGuard
};

/**
Expand Down Expand Up @@ -517,7 +534,7 @@ export interface Route {
* When using a function rather than DI tokens, the function can call `inject` to get any required
* dependencies. This `inject` call must be done in a synchronous context.
*/
canActivate?: Array<CanActivateFn|any>;
canActivate?: Array<CanActivateFn|DeprecatedGuard>;
/**
* An array of `CanMatchFn` or DI tokens used to look up `CanMatch()`
* handlers, in order to determine if the current user is allowed to
Expand All @@ -526,7 +543,7 @@ export interface Route {
* When using a function rather than DI tokens, the function can call `inject` to get any required
* dependencies. This `inject` call must be done in a synchronous context.
*/
canMatch?: Array<Type<CanMatch>|InjectionToken<CanMatchFn>|CanMatchFn>;
canMatch?: Array<CanMatchFn|DeprecatedGuard>;
/**
* An array of `CanActivateChildFn` or DI tokens used to look up `CanActivateChild()` handlers,
* in order to determine if the current user is allowed to activate
Expand All @@ -535,7 +552,7 @@ export interface Route {
* When using a function rather than DI tokens, the function can call `inject` to get any required
* dependencies. This `inject` call must be done in a synchronous context.
*/
canActivateChild?: Array<CanActivateChildFn|any>;
canActivateChild?: Array<CanActivateChildFn|DeprecatedGuard>;
/**
* An array of `CanDeactivateFn` or DI tokens used to look up `CanDeactivate()`
* handlers, in order to determine if the current user is allowed to
Expand All @@ -544,7 +561,7 @@ export interface Route {
* When using a function rather than DI tokens, the function can call `inject` to get any required
* dependencies. This `inject` call must be done in a synchronous context.
*/
canDeactivate?: Array<CanDeactivateFn<any>|any>;
canDeactivate?: Array<CanDeactivateFn<any>|DeprecatedGuard>;
/**
* An array of `CanLoadFn` or DI tokens used to look up `CanLoad()`
* handlers, in order to determine if the current user is allowed to
Expand All @@ -554,7 +571,7 @@ export interface Route {
* dependencies. This `inject` call must be done in a synchronous context.
* @deprecated Use `canMatch` instead
*/
canLoad?: Array<CanLoadFn|any>;
canLoad?: Array<CanLoadFn|DeprecatedGuard>;
/**
* Additional developer-defined data provided to the component via
* `ActivatedRoute`. By default, no additional data is passed.
Expand Down Expand Up @@ -696,6 +713,8 @@ export interface LoadedRouterConfig {
* ```
*
* @publicApi
* @deprecated Use plain JavaScript functions instead.
* @see CanActivateFn
*/
export interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Expand Down Expand Up @@ -791,6 +810,8 @@ export type CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSn
* ```
*
* @publicApi
* @deprecated Use plain JavaScript functions instead.
* @see CanActivateChildFn
*/
export interface CanActivateChild {
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Expand Down Expand Up @@ -880,6 +901,8 @@ export type CanActivateChildFn = (childRoute: ActivatedRouteSnapshot, state: Rou
* ```
*
* @publicApi
* @deprecated Use plain JavaScript functions instead.
* @see CanDeactivateFn
*/
export interface CanDeactivate<T> {
canDeactivate(
Expand Down Expand Up @@ -982,6 +1005,8 @@ export type CanDeactivateFn<T> =
* ```
*
* @publicApi
* @deprecated Use plain JavaScript functions instead.
* @see CanMatchFn
*/
export interface CanMatch {
canMatch(route: Route, segments: UrlSegment[]):
Expand Down Expand Up @@ -1112,6 +1137,8 @@ export type CanMatchFn = (route: Route, segments: UrlSegment[]) =>
* The order of execution is: BaseGuard, ChildGuard, BaseDataResolver, ChildDataResolver.
*
* @publicApi
* @deprecated Use plain JavaScript functions instead.
* @see ResolveFn
*/
export interface Resolve<T> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T>|Promise<T>|T;
Expand Down Expand Up @@ -1196,7 +1223,7 @@ export type ResolveFn<T> = (route: ActivatedRouteSnapshot, state: RouterStateSna
* ```
*
* @publicApi
* @deprecated Use `CanMatch` instead
* @deprecated Use `CanMatchFn` instead
*/
export interface CanLoad {
canLoad(route: Route, segments: UrlSegment[]):
Expand Down
13 changes: 7 additions & 6 deletions packages/router/src/operators/check_guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {concat, defer, from, MonoTypeOperatorFunction, Observable, of, OperatorF
import {concatMap, first, map, mergeMap, tap} from 'rxjs/operators';

import {ActivationStart, ChildActivationStart, Event} from '../events';
import {CanActivateChild, CanActivateChildFn, CanActivateFn, Route} from '../models';
import {CanActivateChild, CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanLoadFn, CanMatchFn, Route} from '../models';
import {redirectingNavigationError} from '../navigation_canceling_error';
import {NavigationTransition} from '../navigation_transition';
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../router_state';
Expand Down Expand Up @@ -142,7 +142,8 @@ function runCanActivateChild(
getTokenOrFunctionIdentity<CanActivateChild>(canActivateChild, closestInjector);
const guardVal = isCanActivateChild(guard) ?
guard.canActivateChild(futureARS, futureRSS) :
closestInjector.runInContext(() => guard(futureARS, futureRSS));
closestInjector.runInContext(
() => (guard as CanActivateChildFn)(futureARS, futureRSS));
return wrapIntoObservable(guardVal).pipe(first());
});
return of(guardsMapped).pipe(prioritizedGuardValue());
Expand All @@ -161,8 +162,8 @@ function runCanDeactivate(
const guard = getTokenOrFunctionIdentity<any>(c, closestInjector);
const guardVal = isCanDeactivate(guard) ?
guard.canDeactivate(component, currARS, currRSS, futureRSS) :
closestInjector.runInContext<boolean|UrlTree>(
() => guard(component, currARS, currRSS, futureRSS));
closestInjector.runInContext(
() => (guard as CanDeactivateFn<any>)(component, currARS, currRSS, futureRSS));
return wrapIntoObservable(guardVal).pipe(first());
});
return of(canDeactivateObservables).pipe(prioritizedGuardValue());
Expand All @@ -180,7 +181,7 @@ export function runCanLoadGuards(
const guard = getTokenOrFunctionIdentity<any>(injectionToken, injector);
const guardVal = isCanLoad(guard) ?
guard.canLoad(route, segments) :
injector.runInContext<boolean|UrlTree>(() => guard(route, segments));
injector.runInContext(() => (guard as CanLoadFn)(route, segments));
return wrapIntoObservable(guardVal);
});

Expand Down Expand Up @@ -213,7 +214,7 @@ export function runCanMatchGuards(
const guard = getTokenOrFunctionIdentity(injectionToken, injector);
const guardVal = isCanMatch(guard) ?
guard.canMatch(route, segments) :
injector.runInContext<boolean|UrlTree>(() => guard(route, segments));
injector.runInContext(() => (guard as CanMatchFn)(route, segments));
return wrapIntoObservable(guardVal);
});

Expand Down