diff --git a/src/cdk/a11y/focus-trap.ts b/src/cdk/a11y/focus-trap.ts index a1205cdf58a..4bcb4bec054 100644 --- a/src/cdk/a11y/focus-trap.ts +++ b/src/cdk/a11y/focus-trap.ts @@ -17,7 +17,7 @@ import { Inject, } from '@angular/core'; import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {InteractivityChecker} from './interactivity-checker'; import {DOCUMENT} from '@angular/common'; @@ -271,7 +271,7 @@ export class FocusTrap { if (this._ngZone.isStable) { fn(); } else { - this._ngZone.onStable.asObservable().pipe(first()).subscribe(fn); + this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(fn); } } } diff --git a/src/cdk/a11y/list-key-manager.spec.ts b/src/cdk/a11y/list-key-manager.spec.ts index 742b9399027..507a7cb0d51 100644 --- a/src/cdk/a11y/list-key-manager.spec.ts +++ b/src/cdk/a11y/list-key-manager.spec.ts @@ -1,5 +1,5 @@ import {DOWN_ARROW, TAB, UP_ARROW} from '@angular/cdk/keycodes'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {QueryList} from '@angular/core'; import {fakeAsync, tick} from '@angular/core/testing'; import {createKeyboardEvent} from '../testing/event-objects'; @@ -196,7 +196,7 @@ describe('Key managers', () => { it('should emit tabOut when the tab key is pressed', () => { let spy = jasmine.createSpy('tabOut spy'); - keyManager.tabOut.pipe(first()).subscribe(spy); + keyManager.tabOut.pipe(take(1)).subscribe(spy); keyManager.onKeydown(fakeKeyEvents.tab); expect(spy).toHaveBeenCalled(); diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index 6b26825dc23..bf27da13302 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -12,7 +12,7 @@ import {OverlayConfig} from './overlay-config'; import {OverlayKeyboardDispatcher} from './keyboard/overlay-keyboard-dispatcher'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; /** @@ -69,7 +69,7 @@ export class OverlayRef implements PortalOutlet { // Update the position once the zone is stable so that the overlay will be fully rendered // before attempting to position it, as the position may depend on the size of the rendered // content. - this._ngZone.onStable.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => { this.updatePosition(); }); diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 58d145dde1e..f848074a695 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -18,7 +18,7 @@ import { } from '@angular/cdk/overlay'; import {TemplatePortal} from '@angular/cdk/portal'; import {filter} from 'rxjs/operators/filter'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {switchMap} from 'rxjs/operators/switchMap'; import {tap} from 'rxjs/operators/tap'; import {delay} from 'rxjs/operators/delay'; @@ -368,7 +368,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy { * stream every time the option list changes. */ private _subscribeToClosingActions(): Subscription { - const firstStable = this._zone.onStable.asObservable().pipe(first()); + const firstStable = this._zone.onStable.asObservable().pipe(take(1)); const optionChanges = this.autocomplete.options.changes.pipe( tap(() => this._positionStrategy.recalculateLastPosition()), // Defer emitting to the stream until the next tick, because changing @@ -387,7 +387,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy { return this.panelClosingActions; }), // when the first closing event occurs... - first() + take(1) ) // set the value, close the panel, and complete. .subscribe(event => this._setValueAndClose(event)); diff --git a/src/lib/datepicker/calendar.ts b/src/lib/datepicker/calendar.ts index 591b317e797..aeef7512aab 100644 --- a/src/lib/datepicker/calendar.ts +++ b/src/lib/datepicker/calendar.ts @@ -36,7 +36,7 @@ import { SimpleChanges, } from '@angular/core'; import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats} from '@angular/material/core'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {Subscription} from 'rxjs/Subscription'; import {createMissingDateImplError} from './datepicker-errors'; import {MatDatepickerIntl} from './datepicker-intl'; @@ -261,7 +261,7 @@ export class MatCalendar implements AfterContentInit, OnDestroy, OnChanges { /** Focuses the active cell after the microtask queue is empty. */ _focusActiveCell() { this._ngZone.runOutsideAngular(() => { - this._ngZone.onStable.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => { this._elementRef.nativeElement.querySelector('.mat-calendar-body-active').focus(); }); }); diff --git a/src/lib/datepicker/datepicker.ts b/src/lib/datepicker/datepicker.ts index d8443626662..cc3bcbb5ec3 100644 --- a/src/lib/datepicker/datepicker.ts +++ b/src/lib/datepicker/datepicker.ts @@ -18,7 +18,7 @@ import { ScrollStrategy, } from '@angular/cdk/overlay'; import {ComponentPortal} from '@angular/cdk/portal'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import { AfterContentInit, ChangeDetectionStrategy, @@ -345,7 +345,7 @@ export class MatDatepicker implements OnDestroy { componentRef.instance.datepicker = this; // Update the position once the calendar has rendered. - this._ngZone.onStable.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => { this._popupRef.updatePosition(); }); } diff --git a/src/lib/dialog/dialog-ref.ts b/src/lib/dialog/dialog-ref.ts index 76e22a0e8ae..e3b37957847 100644 --- a/src/lib/dialog/dialog-ref.ts +++ b/src/lib/dialog/dialog-ref.ts @@ -8,7 +8,7 @@ import {OverlayRef, GlobalPositionStrategy} from '@angular/cdk/overlay'; import {filter} from 'rxjs/operators/filter'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {DialogPosition} from './dialog-config'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; @@ -50,7 +50,7 @@ export class MatDialogRef { // Emit when opening animation completes _containerInstance._animationStateChanged.pipe( filter(event => event.phaseName === 'done' && event.toState === 'enter'), - first() + take(1) ) .subscribe(() => { this._afterOpen.next(); @@ -60,7 +60,7 @@ export class MatDialogRef { // Dispose overlay when closing animation is complete _containerInstance._animationStateChanged.pipe( filter(event => event.phaseName === 'done' && event.toState === 'exit'), - first() + take(1) ) .subscribe(() => { this._overlayRef.dispose(); @@ -80,7 +80,7 @@ export class MatDialogRef { // Transition the backdrop in parallel to the dialog. this._containerInstance._animationStateChanged.pipe( filter(event => event.phaseName === 'start'), - first() + take(1) ) .subscribe(() => { this._beforeClose.next(dialogResult); diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index c3fda637f18..c1046cfa3e5 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -8,7 +8,7 @@ import {animate, state, style, transition, trigger} from '@angular/animations'; import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {startWith} from 'rxjs/operators/startWith'; import { AfterContentChecked, @@ -236,7 +236,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte this._showAlwaysAnimate = true; this._floatPlaceholder = 'always'; - fromEvent(this._placeholder.nativeElement, 'transitionend').pipe(first()).subscribe(() => { + fromEvent(this._placeholder.nativeElement, 'transitionend').pipe(take(1)).subscribe(() => { this._showAlwaysAnimate = false; }); diff --git a/src/lib/icon/icon.ts b/src/lib/icon/icon.ts index e99a4449b3e..6022a85e27a 100644 --- a/src/lib/icon/icon.ts +++ b/src/lib/icon/icon.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import { Attribute, ChangeDetectionStrategy, @@ -130,7 +130,7 @@ export class MatIcon extends _MatIconMixinBase implements OnChanges, OnInit, Can if (this.svgIcon) { const [namespace, iconName] = this._splitIconName(this.svgIcon); - this._iconRegistry.getNamedSvgIcon(iconName, namespace).pipe(first()).subscribe( + this._iconRegistry.getNamedSvgIcon(iconName, namespace).pipe(take(1)).subscribe( svg => this._setSvgElement(svg), (err: Error) => console.log(`Error retrieving icon: ${err.message}`) ); diff --git a/src/lib/menu/menu-directive.ts b/src/lib/menu/menu-directive.ts index b63afba0c68..3a473e11734 100644 --- a/src/lib/menu/menu-directive.ts +++ b/src/lib/menu/menu-directive.ts @@ -12,7 +12,7 @@ import {Direction} from '@angular/cdk/bidi'; import {ESCAPE, LEFT_ARROW, RIGHT_ARROW} from '@angular/cdk/keycodes'; import {startWith} from 'rxjs/operators/startWith'; import {switchMap} from 'rxjs/operators/switchMap'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import { AfterContentInit, ChangeDetectionStrategy, @@ -202,7 +202,7 @@ export class MatMenu implements AfterContentInit, MatMenuPanel, OnDestroy { return this._ngZone.onStable .asObservable() - .pipe(first(), switchMap(() => this._hovered())); + .pipe(take(1), switchMap(() => this._hovered())); } /** Handle a keyboard event from the menu, delegating to the appropriate action. */ diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index f7c8c668b2f..1e652f7f94e 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -19,7 +19,7 @@ import { ViewportRuler, } from '@angular/cdk/overlay'; import {filter} from 'rxjs/operators/filter'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {map} from 'rxjs/operators/map'; import {startWith} from 'rxjs/operators/startWith'; import {takeUntil} from 'rxjs/operators/takeUntil'; @@ -528,7 +528,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, this._changeDetectorRef.markForCheck(); // Set the font size on the panel element once it exists. - this._ngZone.onStable.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => { if (this._triggerFontSize && this.overlayDir.overlayRef && this.overlayDir.overlayRef.overlayElement) { this.overlayDir.overlayRef.overlayElement.style.fontSize = `${this._triggerFontSize}px`; @@ -712,7 +712,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, * Callback that is invoked when the overlay panel has been attached. */ _onAttached(): void { - this.overlayDir.positionChange.pipe(first()).subscribe(() => { + this.overlayDir.positionChange.pipe(take(1)).subscribe(() => { this._changeDetectorRef.detectChanges(); this._calculateOverlayOffsetX(); this.panel.nativeElement.scrollTop = this._scrollTop; diff --git a/src/lib/sidenav/drawer.ts b/src/lib/sidenav/drawer.ts index 934eb5795b6..e41b45fb317 100644 --- a/src/lib/sidenav/drawer.ts +++ b/src/lib/sidenav/drawer.ts @@ -32,7 +32,7 @@ import { import {DOCUMENT} from '@angular/common'; import {merge} from 'rxjs/observable/merge'; import {filter} from 'rxjs/operators/filter'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {startWith} from 'rxjs/operators/startWith'; import {takeUntil} from 'rxjs/operators/takeUntil'; import {map} from 'rxjs/operators/map'; @@ -345,7 +345,7 @@ export class MatDrawer implements AfterContentInit, OnDestroy { // TODO(crisbeto): This promise is here for backwards-compatibility. // It should be removed next time we do breaking changes in the drawer. return new Promise(resolve => { - this.openedChange.pipe(first()).subscribe(open => { + this.openedChange.pipe(take(1)).subscribe(open => { resolve(new MatDrawerToggleResult(open ? 'open' : 'close', true)); }); }); @@ -515,7 +515,7 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy { // NOTE: We need to wait for the microtask queue to be empty before validating, // since both drawers may be swapping positions at the same time. drawer.onPositionChanged.pipe(takeUntil(this._drawers.changes)).subscribe(() => { - this._ngZone.onMicrotaskEmpty.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onMicrotaskEmpty.asObservable().pipe(take(1)).subscribe(() => { this._validateDrawers(); }); }); diff --git a/src/lib/snack-bar/snack-bar-container.ts b/src/lib/snack-bar/snack-bar-container.ts index 42e8b813509..bbefc940aa5 100644 --- a/src/lib/snack-bar/snack-bar-container.ts +++ b/src/lib/snack-bar/snack-bar-container.ts @@ -31,7 +31,7 @@ import { ComponentPortal, CdkPortalOutlet, } from '@angular/cdk/portal'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {AnimationCurves, AnimationDurations} from '@angular/material/core'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; @@ -170,7 +170,7 @@ export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy * errors where we end up removing an element which is in the middle of an animation. */ private _completeExit() { - this._ngZone.onMicrotaskEmpty.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onMicrotaskEmpty.asObservable().pipe(take(1)).subscribe(() => { this._onExit.next(); this._onExit.complete(); }); diff --git a/src/lib/snack-bar/snack-bar.ts b/src/lib/snack-bar/snack-bar.ts index 3ac13aa8a11..16c101d9557 100644 --- a/src/lib/snack-bar/snack-bar.ts +++ b/src/lib/snack-bar/snack-bar.ts @@ -11,7 +11,7 @@ import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout'; import {Overlay, OverlayConfig, OverlayRef} from '@angular/cdk/overlay'; import {ComponentPortal, ComponentType, PortalInjector} from '@angular/cdk/portal'; import {ComponentRef, Injectable, Injector, Optional, SkipSelf} from '@angular/core'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {takeUntil} from 'rxjs/operators/takeUntil'; import {SimpleSnackBar} from './simple-snack-bar'; import {MAT_SNACK_BAR_DATA, MatSnackBarConfig} from './snack-bar-config'; @@ -152,7 +152,7 @@ export class MatSnackBar { // appropriate. This class is applied to the overlay element because the overlay must expand to // fill the width of the screen for full width snackbars. this._breakpointObserver.observe(Breakpoints.Handset).pipe( - takeUntil(overlayRef.detachments().pipe(first())) + takeUntil(overlayRef.detachments().pipe(take(1))) ).subscribe(state => { if (state.matches) { overlayRef.overlayElement.classList.add('mat-snack-bar-handset'); diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts index c41a731f46a..7c2a1edddf1 100644 --- a/src/lib/tooltip/tooltip.ts +++ b/src/lib/tooltip/tooltip.ts @@ -24,7 +24,7 @@ import { } from '@angular/cdk/overlay'; import {Platform} from '@angular/cdk/platform'; import {ComponentPortal} from '@angular/cdk/portal'; -import {first} from 'rxjs/operators/first'; +import {take} from 'rxjs/operators/take'; import {merge} from 'rxjs/observable/merge'; import {ScrollDispatcher} from '@angular/cdk/scrolling'; import { @@ -389,7 +389,7 @@ export class MatTooltip implements OnDestroy { this._tooltipInstance.message = this.message; this._tooltipInstance._markForCheck(); - this._ngZone.onMicrotaskEmpty.asObservable().pipe(first()).subscribe(() => { + this._ngZone.onMicrotaskEmpty.asObservable().pipe(take(1)).subscribe(() => { if (this._tooltipInstance) { this._overlayRef!.updatePosition(); } diff --git a/tools/package-tools/rollup-globals.ts b/tools/package-tools/rollup-globals.ts index 1d08c970d5a..701b2c5c76c 100644 --- a/tools/package-tools/rollup-globals.ts +++ b/tools/package-tools/rollup-globals.ts @@ -74,6 +74,7 @@ export const rollupGlobals = { 'rxjs/operators/debounceTime': 'Rx.Observable', 'rxjs/operators/takeUntil': 'Rx.Observable', 'rxjs/operators/first': 'Rx.Observable', + 'rxjs/operators/take': 'Rx.Observable', 'rxjs/operators/filter': 'Rx.Observable', 'rxjs/operators/map': 'Rx.Observable', 'rxjs/operators/tap': 'Rx.Observable',