diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts
index 4a171a3f3a36d6d70e6ba8cf0c6de3bff0c0b9b9..faaf3b9fb52d2bb0ab215e939ad0a772b57b833e 100644
--- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts
+++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts
@@ -6,7 +6,7 @@ import {
   Subject,
   Subscription
 } from 'rxjs';
-import { switchMap, distinctUntilChanged, first, map } from 'rxjs/operators';
+import { switchMap, distinctUntilChanged, first, map, take } from 'rxjs/operators';
 import { animate, state, style, transition, trigger } from '@angular/animations';
 import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
@@ -126,7 +126,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
         this.animationState = 'ready';
         this.filterValues$.next(rd);
       }));
-      this.subs.push(newValues$.pipe(first()).subscribe((rd) => {
+      this.subs.push(newValues$.pipe(take(1)).subscribe((rd) => {
         this.isLastPage$.next(hasNoValue(rd.payload.next))
       }));
     }));
@@ -189,7 +189,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
    * @param data The string from the input field
    */
   onSubmit(data: any) {
-    this.selectedValues.pipe(first()).subscribe((selectedValues) => {
+    this.selectedValues.pipe(take(1)).subscribe((selectedValues) => {
         if (isNotEmpty(data)) {
           this.router.navigate([this.getSearchLink()], {
             queryParams:
@@ -258,7 +258,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
    */
   findSuggestions(data): void {
     if (isNotEmpty(data)) {
-      this.searchConfigService.searchOptions.pipe(first()).subscribe(
+      this.searchConfigService.searchOptions.pipe(take(1)).subscribe(
         (options) => {
           this.filterSearchResults = this.searchService.getFacetValuesFor(this.filterConfig, 1, options, data.toLowerCase())
             .pipe(
diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-filter.component.ts
index 87f8edc1ea4e9a5b2e6c91b6d4ee93a3a8393d17..ec239e362807ab9abf5e97453fb63437c857c65d 100644
--- a/src/app/+search-page/search-filters/search-filter/search-filter.component.ts
+++ b/src/app/+search-page/search-filters/search-filter/search-filter.component.ts
@@ -1,5 +1,5 @@
 
-import {first} from 'rxjs/operators';
+import { first, take } from 'rxjs/operators';
 import { Component, Input, OnInit } from '@angular/core';
 import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
 import { SearchFilterService } from './search-filter.service';
@@ -37,7 +37,7 @@ export class SearchFilterComponent implements OnInit {
    * Else, the filter should initially be collapsed
    */
   ngOnInit() {
-    this.getSelectedValues().pipe(first()).subscribe((isActive) => {
+    this.getSelectedValues().pipe(take(1)).subscribe((isActive) => {
       if (this.filter.isOpenByDefault || isNotEmpty(isActive)) {
         this.initialExpand();
       } else {
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 7d4bfe4f3381be14dccc03baceb9d3c216f7c121..32ba6e752ffca3e0d90faf2036b0d19e8764a6a0 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -64,7 +64,7 @@ export class AppComponent implements OnInit, AfterViewInit {
 
     // Whether is not authenticathed try to retrieve a possible stored auth token
     this.store.pipe(select(isAuthenticated),
-      first(),
+      take(1),
       filter((authenticated) => !authenticated)
     ).subscribe((authenticated) => this.authService.checkAuthenticationToken());
 
diff --git a/src/app/core/auth/auth.effects.ts b/src/app/core/auth/auth.effects.ts
index c57fa3f70e86fa086cd043b82fff13a47f2f1330..56a5411ef2175d50268fc6c568afcd725fa91924 100644
--- a/src/app/core/auth/auth.effects.ts
+++ b/src/app/core/auth/auth.effects.ts
@@ -47,7 +47,7 @@ export class AuthEffects {
       ofType(AuthActionTypes.AUTHENTICATE),
       switchMap((action: AuthenticateAction) => {
         return this.authService.authenticate(action.payload.email, action.payload.password).pipe(
-          first(),
+          take(1),
           map((response: AuthStatus) => new AuthenticationSuccessAction(response.token)),
           catchError((error) => observableOf(new AuthenticationErrorAction(error)))
         );
@@ -127,7 +127,7 @@ export class AuthEffects {
     switchMap(() => {
       return this.store.pipe(
         select(isAuthenticated),
-        first(),
+        take(1),
         filter((authenticated) => !authenticated),
         tap(() => this.authService.removeToken()),
         tap(() => this.authService.resetAuthenticationError())
diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts
index 67f533d4adc9914ac204f02e1c98b67450bb5c3f..66fe65a22ede3fc16dc6a75912abdc6cfa34aa7e 100644
--- a/src/app/core/auth/auth.service.ts
+++ b/src/app/core/auth/auth.service.ts
@@ -277,7 +277,7 @@ export class AuthService {
   public isTokenExpiring(): Observable<boolean> {
     return this.store.pipe(
       select(isTokenRefreshing),
-      first(),
+      take(1),
       map((isRefreshing: boolean) => {
         if (this.isTokenExpired() || isRefreshing) {
           return false;
@@ -360,7 +360,7 @@ export class AuthService {
    */
   public redirectToPreviousUrl() {
     this.getRedirectUrl().pipe(
-      first())
+      take(1))
       .subscribe((redirectUrl) => {
 
         if (isNotEmpty(redirectUrl)) {
diff --git a/src/app/core/auth/server-auth.service.ts b/src/app/core/auth/server-auth.service.ts
index c83410f6e300033cf2d2685c6c8cd0fd8e24d1c8..903926fbcfb9dc25f36e3dac40cfa70a3f0c0de6 100644
--- a/src/app/core/auth/server-auth.service.ts
+++ b/src/app/core/auth/server-auth.service.ts
@@ -1,4 +1,4 @@
-import { first, map, switchMap } from 'rxjs/operators';
+import { first, map, switchMap, take } from 'rxjs/operators';
 import { Injectable } from '@angular/core';
 
 import { Observable } from 'rxjs';
@@ -62,7 +62,7 @@ export class ServerAuthService extends AuthService {
    */
   public redirectToPreviousUrl() {
     this.getRedirectUrl().pipe(
-      first())
+      take(1))
       .subscribe((redirectUrl) => {
         if (isNotEmpty(redirectUrl)) {
           // override the route reuse strategy
diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts
index 52ec4382ae1f103bf89601eaa8972a31cc1fcab1..1dc255f26e91a3d9a6ab9ba012527260c6942de4 100644
--- a/src/app/core/cache/builders/remote-data-build.service.ts
+++ b/src/app/core/cache/builders/remote-data-build.service.ts
@@ -5,7 +5,15 @@ import {
   race as observableRace
 } from 'rxjs';
 import { Injectable } from '@angular/core';
-import { distinctUntilChanged, first, flatMap, map, startWith, switchMap } from 'rxjs/operators';
+import {
+  distinctUntilChanged,
+  first,
+  flatMap,
+  map,
+  startWith,
+  switchMap,
+  take
+} from 'rxjs/operators';
 import { hasValue, hasValueOperator, isEmpty, isNotEmpty } from '../../../shared/empty.util';
 import { PaginatedList } from '../../data/paginated-list';
 import { RemoteData } from '../../data/remote-data';
@@ -44,7 +52,7 @@ export class RemoteDataBuildService {
       href$.pipe(getRequestFromRequestHref(this.requestService)),
       requestUUID$.pipe(getRequestFromRequestUUID(this.requestService)),
     ).pipe(
-      first()
+      take(1)
     );
 
     // always use self link if that is cached, only if it isn't, get it via the response.
diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts
index 44297d6f619b99308fa0feadc43228977a4a8e20..40f41be14d9ccd74eaa5dbca1ddfe7fe418f98c4 100644
--- a/src/app/core/cache/object-cache.service.ts
+++ b/src/app/core/cache/object-cache.service.ts
@@ -1,6 +1,6 @@
 import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
 
-import { distinctUntilChanged, filter, first, map, mergeMap, } from 'rxjs/operators';
+import { distinctUntilChanged, filter, first, map, mergeMap, take, } from 'rxjs/operators';
 import { Injectable } from '@angular/core';
 import { MemoizedSelector, select, Store } from '@ngrx/store';
 import { IndexName } from '../index/index.reducer';
@@ -165,7 +165,7 @@ export class ObjectCacheService {
 
     this.store.pipe(
       select(selfLinkFromUuidSelector(uuid)),
-      first()
+      take(1)
     ).subscribe((selfLink: string) => result = this.hasBySelfLink(selfLink));
 
     return result;
@@ -184,7 +184,7 @@ export class ObjectCacheService {
     let result = false;
 
     this.store.pipe(select(entryFromSelfLinkSelector(selfLink)),
-      first()
+      take(1)
     ).subscribe((entry: ObjectCacheEntry) => result = this.isValid(entry));
 
     return result;
diff --git a/src/app/core/cache/server-sync-buffer.effects.ts b/src/app/core/cache/server-sync-buffer.effects.ts
index 5a0a5527d1ff2f09a567900fa3cebc96fdb76d69..d0a194705b1ee728f35e324250506bab7699e956 100644
--- a/src/app/core/cache/server-sync-buffer.effects.ts
+++ b/src/app/core/cache/server-sync-buffer.effects.ts
@@ -1,4 +1,4 @@
-import { delay, exhaustMap, first, map, switchMap, tap } from 'rxjs/operators';
+import { delay, exhaustMap, first, map, switchMap, take, tap } from 'rxjs/operators';
 import { Inject, Injectable } from '@angular/core';
 import { Actions, Effect, ofType } from '@ngrx/effects';
 import {
@@ -56,7 +56,7 @@ export class ServerSyncBufferEffects {
       switchMap((action: CommitSSBAction) => {
         return this.store.pipe(
           select(serverSyncBufferSelector()),
-          first(), /* necessary, otherwise delay will not have any effect after the first run */
+          take(1), /* necessary, otherwise delay will not have any effect after the first run */
           switchMap((bufferState: ServerSyncBufferState) => {
             const actions: Array<Observable<Action>> = bufferState.buffer
               .filter((entry: ServerSyncBufferEntry) => {
@@ -95,7 +95,7 @@ export class ServerSyncBufferEffects {
    * @returns {Observable<Action>} ApplyPatchObjectCacheAction to be dispatched
    */
   private applyPatch(href: string): Observable<Action> {
-    const patchObject = this.objectCache.getBySelfLink(href).pipe(first());
+    const patchObject = this.objectCache.getBySelfLink(href).pipe(take(1));
 
     return patchObject.pipe(
       map((object) => {
diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts
index db3882ac08b4b03b543601d3f10e6814ab945654..4bbe775f3b572cc21ce12da296ee019b10065b33 100644
--- a/src/app/core/data/data.service.ts
+++ b/src/app/core/data/data.service.ts
@@ -1,4 +1,4 @@
-import { distinctUntilChanged, filter, first, map, switchMap, take } from 'rxjs/operators';
+import { delay, distinctUntilChanged, filter, find, switchMap, map, take, tap } from 'rxjs/operators';
 import { Observable } from 'rxjs';
 import { Store } from '@ngrx/store';
 import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
@@ -94,7 +94,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain>
       map((endpoint: string) => this.getFindByIDHref(endpoint, id)));
 
     hrefObs.pipe(
-      first((href: string) => hasValue(href)))
+      find((href: string) => hasValue(href)))
       .subscribe((href: string) => {
         const request = new FindByIDRequest(this.requestService.generateRequestId(), href, id);
         this.requestService.configure(request);
diff --git a/src/app/core/metadata/metadata.service.ts b/src/app/core/metadata/metadata.service.ts
index 8bec058d084f917ee0b60055005a12739c147fa2..e73613fddbf397acea5e3ec7b25f9cd9275eed63 100644
--- a/src/app/core/metadata/metadata.service.ts
+++ b/src/app/core/metadata/metadata.service.ts
@@ -1,4 +1,12 @@
-import { catchError, distinctUntilKeyChanged, filter, first, map, take } from 'rxjs/operators';
+import {
+  catchError,
+  distinctUntilKeyChanged,
+  filter,
+  find,
+  first,
+  map,
+  take
+} from 'rxjs/operators';
 import { Inject, Injectable } from '@angular/core';
 import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
 
@@ -261,7 +269,7 @@ export class MetadataService {
       const item = this.currentObject.value as Item;
       item.getFiles()
         .pipe(
-          first((files) => isNotEmpty(files)),
+          find((files) => isNotEmpty(files)),
           catchError((error) => {
             console.debug(error.message);
             return []
@@ -269,7 +277,7 @@ export class MetadataService {
         .subscribe((bitstreams: Bitstream[]) => {
           for (const bitstream of bitstreams) {
             bitstream.format.pipe(
-              first(),
+              take(1),
               catchError((error: Error) => {
                 console.debug(error.message);
                 return []
diff --git a/src/app/core/shared/operators.ts b/src/app/core/shared/operators.ts
index 4e6a95ff11fd673b820e2270b87360f5bae17c0c..388c4289e2ace13f3f2176c21f916b4122d4126f 100644
--- a/src/app/core/shared/operators.ts
+++ b/src/app/core/shared/operators.ts
@@ -1,5 +1,5 @@
 import { Observable } from 'rxjs';
-import { filter, first, flatMap, map, tap } from 'rxjs/operators';
+import { filter, find, first, flatMap, map, tap } from 'rxjs/operators';
 import { hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util';
 import { DSOSuccessResponse, RestResponse } from '../cache/response.models';
 import { RemoteData } from '../data/remote-data';
@@ -60,7 +60,7 @@ export const getRemoteDataPayload = () =>
 
 export const getSucceededRemoteData = () =>
   <T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
-    source.pipe(first((rd: RemoteData<T>) => rd.hasSucceeded));
+    source.pipe(find((rd: RemoteData<T>) => rd.hasSucceeded));
 
 export const toDSpaceObjectListRD = () =>
   <T extends DSpaceObject>(source: Observable<RemoteData<PaginatedList<SearchResult<T>>>>): Observable<RemoteData<PaginatedList<T>>> =>