From 04ff4a7525095b149c64496f80585e63c0d4bbad Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 18 Dec 2024 10:20:17 +0700 Subject: [PATCH 1/3] Replaced toPromise with lastValueFrom --- .../import-questions-dialog.component.ts | 3 ++- .../question-dialog.service.ts | 5 ++-- .../machine-api/remote-translation-engine.ts | 12 ++++----- .../src/app/project/project.component.ts | 4 +-- .../page-not-found.component.ts | 4 +-- .../app/translate/editor/editor.component.ts | 27 ++++++++++--------- .../src/xforge-common/dialog.service.ts | 4 +-- .../xforge-common/retrying-request.service.ts | 10 +++---- .../testing-retrying-request.service.ts | 4 +-- .../src/xforge-common/user.service.ts | 4 +-- 10 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.ts index a119a5053f..a2762d7df0 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/checking/import-questions-dialog/import-questions-dialog.component.ts @@ -6,6 +6,7 @@ import { TranslocoService } from '@ngneat/transloco'; import { Canon, VerseRef } from '@sillsdev/scripture'; import { Question } from 'realtime-server/lib/esm/scriptureforge/models/question'; import { fromVerseRef, toVerseRef } from 'realtime-server/lib/esm/scriptureforge/models/verse-ref-data'; +import { lastValueFrom } from 'rxjs'; import { CsvService } from 'xforge-common/csv-service.service'; import { DialogService } from 'xforge-common/dialog.service'; import { ExternalUrlService } from 'xforge-common/external-url.service'; @@ -475,7 +476,7 @@ export class ImportQuestionsDialogComponent extends SubscriptionDisposable imple ImportQuestionsConfirmationDialogComponent, data ) as MatDialogRef; - (await dialogRef.afterClosed().toPromise())!.forEach( + (await lastValueFrom(dialogRef.afterClosed())).forEach( (checked, index) => (changesToConfirm[index].checked = checked) ); this.updateSelectAllCheckbox(); diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/checking/question-dialog/question-dialog.service.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/checking/question-dialog/question-dialog.service.ts index 1ad7eaa4eb..15e116e77d 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/checking/question-dialog/question-dialog.service.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/checking/question-dialog/question-dialog.service.ts @@ -3,8 +3,9 @@ import { MatDialogConfig, MatDialogRef } from '@angular/material/dialog'; import { TranslocoService } from '@ngneat/transloco'; import { Operation } from 'realtime-server/lib/esm/common/models/project-rights'; import { Question } from 'realtime-server/lib/esm/scriptureforge/models/question'; -import { SFProjectDomain, SF_PROJECT_RIGHTS } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-rights'; +import { SF_PROJECT_RIGHTS, SFProjectDomain } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-rights'; import { fromVerseRef } from 'realtime-server/lib/esm/scriptureforge/models/verse-ref-data'; +import { lastValueFrom } from 'rxjs'; import { DialogService } from 'xforge-common/dialog.service'; import { FileType } from 'xforge-common/models/file-offline-data'; import { NoticeService } from 'xforge-common/notice.service'; @@ -38,7 +39,7 @@ export class QuestionDialogService { >; // ENHANCE: Put the audio upload logic into QuestionDialogComponent so we can detect if the upload // fails and notify the user without discarding the question. For example, see chapter-audio-dialog.component.ts. - const result: QuestionDialogResult | 'close' | undefined = await dialogRef.afterClosed().toPromise(); + const result: QuestionDialogResult | 'close' | undefined = await lastValueFrom(dialogRef.afterClosed()); if (result == null || result === 'close') { return questionDoc; } diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/machine-api/remote-translation-engine.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/machine-api/remote-translation-engine.ts index c1d3df66b1..9cc4666409 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/machine-api/remote-translation-engine.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/machine-api/remote-translation-engine.ts @@ -113,9 +113,9 @@ export class RemoteTranslationEngine implements InteractiveTranslationEngine { async trainSegment(sourceSegment: string, targetSegment: string, sentenceStart: boolean = true): Promise { const pairDto: SegmentPairDto = { sourceSegment, targetSegment, sentenceStart }; - await this.httpClient - .post(`translation/engines/project:${this.projectId}/actions/trainSegment`, pairDto) - .toPromise(); + await lastValueFrom( + this.httpClient.post(`translation/engines/project:${this.projectId}/actions/trainSegment`, pairDto) + ); } train(): Observable { @@ -126,8 +126,8 @@ export class RemoteTranslationEngine implements InteractiveTranslationEngine { } async startTraining(): Promise { - return this.createBuild(this.projectId) - .pipe( + return lastValueFrom( + this.createBuild(this.projectId).pipe( catchError(err => { if (err.status === 404) { return of(undefined); @@ -136,7 +136,7 @@ export class RemoteTranslationEngine implements InteractiveTranslationEngine { } }) ) - .toPromise(); + ); } listenForTrainingStatus(): Observable { diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/project/project.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/project/project.component.ts index fd3488b5de..cb78ccbac8 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/project/project.component.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/project/project.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { Canon } from '@sillsdev/scripture'; import { SFProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project'; import { SFProjectUserConfig } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-user-config'; -import { Observable } from 'rxjs'; +import { lastValueFrom, Observable } from 'rxjs'; import { distinctUntilChanged, filter, first, map } from 'rxjs/operators'; import { DataLoadingComponent } from 'xforge-common/data-loading-component'; import { DialogService } from 'xforge-common/dialog.service'; @@ -138,7 +138,7 @@ export class ProjectComponent extends DataLoadingComponent implements OnInit { private async navigateToChecking(projectId: string, task: TaskType = 'checking'): Promise { const defaultCheckingLink: string[] = ['/projects', projectId, task]; - const link = await this.resumeCheckingService.checkingLink$.pipe(first()).toPromise(); + const link = await lastValueFrom(this.resumeCheckingService.checkingLink$.pipe(first())); this.router.navigate(link ?? defaultCheckingLink, { replaceUrl: true }); } diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/shared/page-not-found/page-not-found.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/page-not-found/page-not-found.component.ts index af85dcd38d..221a4d682e 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/shared/page-not-found/page-not-found.component.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/page-not-found/page-not-found.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { Router } from '@angular/router'; -import { timer } from 'rxjs'; +import { lastValueFrom, timer } from 'rxjs'; import { map, takeWhile } from 'rxjs/operators'; // All times in milliseconds @@ -20,7 +20,7 @@ export class PageNotFoundComponent { ); constructor(readonly router: Router) { - this.progress.toPromise().then(() => { + lastValueFrom(this.progress).then(() => { this.router.navigateByUrl('/projects'); }); } diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.ts index ed8276c727..3d940979b1 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.ts @@ -39,14 +39,14 @@ import { EditorTabPersistData } from 'realtime-server/lib/esm/scriptureforge/mod import { Note } from 'realtime-server/lib/esm/scriptureforge/models/note'; import { BIBLICAL_TERM_TAG_ICON, NoteTag } from 'realtime-server/lib/esm/scriptureforge/models/note-tag'; import { + getNoteThreadDocId, NoteConflictType, NoteStatus, NoteThread, - NoteType, - getNoteThreadDocId + NoteType } from 'realtime-server/lib/esm/scriptureforge/models/note-thread'; import { ParatextUserProfile } from 'realtime-server/lib/esm/scriptureforge/models/paratext-user-profile'; -import { SFProjectDomain, SF_PROJECT_RIGHTS } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-rights'; +import { SF_PROJECT_RIGHTS, SFProjectDomain } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-rights'; import { SFProjectRole } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-role'; import { TextAnchor } from 'realtime-server/lib/esm/scriptureforge/models/text-anchor'; import { TextType } from 'realtime-server/lib/esm/scriptureforge/models/text-data'; @@ -56,16 +56,17 @@ import { TranslateSource } from 'realtime-server/lib/esm/scriptureforge/models/t import { fromVerseRef } from 'realtime-server/lib/esm/scriptureforge/models/verse-ref-data'; import { DeltaOperation } from 'rich-text'; import { - BehaviorSubject, - Observable, - Subject, - Subscription, asyncScheduler, + BehaviorSubject, combineLatest, firstValueFrom, fromEvent, + lastValueFrom, merge, + Observable, of, + Subject, + Subscription, timer } from 'rxjs'; import { debounceTime, filter, first, map, repeat, retry, switchMap, take, tap, throttleTime } from 'rxjs/operators'; @@ -87,7 +88,7 @@ import { filterNullish } from 'xforge-common/util/rxjs-util'; import { browserLinks, getLinkHTML, isBlink, issuesEmailTemplate, objectId } from 'xforge-common/utils'; import { XFValidators } from 'xforge-common/xfvalidators'; import { environment } from '../../../environments/environment'; -import { NoteThreadDoc, NoteThreadIcon, defaultNoteThreadIcon } from '../../core/models/note-thread-doc'; +import { defaultNoteThreadIcon, NoteThreadDoc, NoteThreadIcon } from '../../core/models/note-thread-doc'; import { SFProjectDoc } from '../../core/models/sf-project-doc'; import { SFProjectProfileDoc } from '../../core/models/sf-project-profile-doc'; import { SF_DEFAULT_TRANSLATE_SHARE_ROLE } from '../../core/models/sf-project-role-info'; @@ -111,15 +112,15 @@ import { TextComponent } from '../../shared/text/text.component'; import { - RIGHT_TO_LEFT_MARK, - VERSE_REGEX, - XmlUtils, canInsertNote, formatFontSizeToRems, getUnsupportedTags, getVerseRefFromSegmentRef, + RIGHT_TO_LEFT_MARK, threadIdFromMouseEvent, - verseRefFromMouseEvent + VERSE_REGEX, + verseRefFromMouseEvent, + XmlUtils } from '../../shared/utils'; import { DraftGenerationService } from '../draft-generation/draft-generation.service'; import { EditorHistoryService } from './editor-history/editor-history.service'; @@ -1551,7 +1552,7 @@ export class EditorComponent extends DataLoadingComponent implements OnDestroy, const currentVerseRef: VerseRef | undefined = this.commenterSelectedVerseRef; this.setNoteFabVisibility('hidden'); - const result: NoteDialogResult | undefined = await dialogRef.afterClosed().toPromise(); + const result: NoteDialogResult | undefined = await lastValueFrom(dialogRef.afterClosed()); if (result != null) { if (result.noteContent != null || result.status != null) { diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/dialog.service.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/dialog.service.ts index 0f9d9d0034..51ca855116 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/dialog.service.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/dialog.service.ts @@ -2,7 +2,7 @@ import { OverlayRef } from '@angular/cdk/overlay'; import { ComponentType } from '@angular/cdk/portal'; import { Injectable } from '@angular/core'; import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog'; -import { Observable } from 'rxjs'; +import { lastValueFrom, Observable } from 'rxjs'; import { hasObjectProp } from '../type-utils'; import { GenericDialogComponent, @@ -43,7 +43,7 @@ export class DialogService { return { dialogRef, - result: dialogRef.afterClosed().toPromise() + result: lastValueFrom(dialogRef.afterClosed()) }; } diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts index 253d4973f7..b69f36fff5 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts @@ -1,5 +1,5 @@ import { Inject, Injectable } from '@angular/core'; -import { Observable, Subject } from 'rxjs'; +import { lastValueFrom, Observable, Subject } from 'rxjs'; import { filter, take } from 'rxjs/operators'; import { CONSOLE, ConsoleInterface } from './browser-globals'; import { CommandErrorCode, CommandService } from './command.service'; @@ -96,7 +96,7 @@ export class RetryingRequest { private async invoke(options: FetchOptions): Promise { while (!this.canceled && this.status !== 'complete') { - const online = await this.online$.pipe(take(1)).toPromise(); + const online = await lastValueFrom(this.online$.pipe(take(1))); if (online !== true) { this.status = 'offline'; await this.uponOnline(); @@ -124,12 +124,12 @@ export class RetryingRequest { } private async uponOnline(): Promise { - await this.online$ - .pipe( + await lastValueFrom( + this.online$.pipe( filter(isOnline => isOnline), take(1) ) - .toPromise(); + ); } private isNetworkError(error: unknown): boolean { diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/testing-retrying-request.service.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/testing-retrying-request.service.ts index 7d48a6227a..d5b7d642a5 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/testing-retrying-request.service.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/testing-retrying-request.service.ts @@ -1,4 +1,4 @@ -import { BehaviorSubject, Observable, Subject } from 'rxjs'; +import { BehaviorSubject, lastValueFrom, Observable, Subject } from 'rxjs'; import { ConsoleInterface } from './browser-globals'; import { FetchOptions, JsonRpcInvocable, RetryingRequest } from './retrying-request.service'; @@ -12,7 +12,7 @@ export class TestingRetryingRequestService { cancel$ = new Subject() ): RetryingRequest { const invocable = { - onlineInvoke: (_url: string, _method: string, _params: string) => invoke.toPromise() + onlineInvoke: (_url: string, _method: string, _params: string) => lastValueFrom(invoke) } as JsonRpcInvocable; const mockConsole = { log: () => {}, error: () => {} } as ConsoleInterface; return new RetryingRequest(invocable, online, cancel$, {} as FetchOptions, mockConsole); diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/user.service.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/user.service.ts index 1983607442..cffc8a2858 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/user.service.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/user.service.ts @@ -5,7 +5,7 @@ import { escapeRegExp } from 'lodash-es'; import merge from 'lodash-es/merge'; import { User } from 'realtime-server/lib/esm/common/models/user'; import { obj } from 'realtime-server/lib/esm/common/utils/obj-path'; -import { combineLatest, from, Observable } from 'rxjs'; +import { combineLatest, from, lastValueFrom, Observable } from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; import { environment } from '../environments/environment'; import { AuthService } from './auth.service'; @@ -116,7 +116,7 @@ export class UserService { disableClose: isConfirmation, width: '280px' }) as MatDialogRef; - const result = await dialogRef.afterClosed().toPromise(); + const result = await lastValueFrom(dialogRef.afterClosed()); if (result != null && result !== 'close') { await currentUserDoc.submitJson0Op(op => { op.set(u => u.displayName, result.displayName); From d312a8fb925c630c14c6d2695496faca4df9a000 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 18 Dec 2024 12:38:02 +0700 Subject: [PATCH 2/3] Fixed tests --- .../translate/editor/editor.component.spec.ts | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.spec.ts index 108cbabeeb..f5d9b8324f 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.spec.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/editor/editor.component.spec.ts @@ -4,13 +4,14 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { Location } from '@angular/common'; import { HttpErrorResponse } from '@angular/common/http'; import { DebugElement, NgZone } from '@angular/core'; -import { ComponentFixture, TestBed, discardPeriodicTasks, fakeAsync, flush, tick } from '@angular/core/testing'; +import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog'; import { MatTooltipHarness } from '@angular/material/tooltip/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Params, Route, Router, RouterModule } from '@angular/router'; import { + createRange, InteractiveTranslatorFactory, LatinWordDetokenizer, LatinWordTokenizer, @@ -18,8 +19,7 @@ import { TranslationSources, WordAlignmentMatrix, WordGraph, - WordGraphArc, - createRange + WordGraphArc } from '@sillsdev/machine'; import { Canon, VerseRef } from '@sillsdev/scripture'; import { merge } from 'lodash-es'; @@ -38,29 +38,29 @@ import { Note, REATTACH_SEPARATOR } from 'realtime-server/lib/esm/scriptureforge import { NoteTag, SF_TAG_ICON } from 'realtime-server/lib/esm/scriptureforge/models/note-tag'; import { AssignedUsers, + getNoteThreadDocId, NoteConflictType, NoteStatus, NoteThread, - NoteType, - getNoteThreadDocId + NoteType } from 'realtime-server/lib/esm/scriptureforge/models/note-thread'; import { ParatextUserProfile } from 'realtime-server/lib/esm/scriptureforge/models/paratext-user-profile'; import { SFProject, SFProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project'; -import { SFProjectRole, isParatextRole } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-role'; +import { isParatextRole, SFProjectRole } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-role'; import { createTestProject, createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-test-data'; import { - SFProjectUserConfig, - getSFProjectUserConfigDocId + getSFProjectUserConfigDocId, + SFProjectUserConfig } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-user-config'; import { TextAnchor } from 'realtime-server/lib/esm/scriptureforge/models/text-anchor'; import { TextType } from 'realtime-server/lib/esm/scriptureforge/models/text-data'; import { TextInfoPermission } from 'realtime-server/lib/esm/scriptureforge/models/text-info-permission'; import { fromVerseRef } from 'realtime-server/lib/esm/scriptureforge/models/verse-ref-data'; import * as RichText from 'rich-text'; -import { BehaviorSubject, Observable, Subject, defer, firstValueFrom, of, take } from 'rxjs'; +import { BehaviorSubject, defer, firstValueFrom, Observable, of, Subject, take } from 'rxjs'; import { anything, capture, deepEqual, instance, mock, resetCalls, verify, when } from 'ts-mockito'; import { ActivatedProjectService } from 'xforge-common/activated-project.service'; import { AuthService } from 'xforge-common/auth.service'; @@ -75,7 +75,7 @@ import { TestOnlineStatusModule } from 'xforge-common/test-online-status.module' import { TestOnlineStatusService } from 'xforge-common/test-online-status.service'; import { TestRealtimeModule } from 'xforge-common/test-realtime.module'; import { TestRealtimeService } from 'xforge-common/test-realtime.service'; -import { TestTranslocoModule, configureTestingModule } from 'xforge-common/test-utils'; +import { configureTestingModule, TestTranslocoModule } from 'xforge-common/test-utils'; import { UICommonModule } from 'xforge-common/ui-common.module'; import { UserService } from 'xforge-common/user.service'; import { isBlink } from 'xforge-common/utils'; @@ -204,6 +204,8 @@ describe('EditorComponent', () => { env.wait(); const dialogMessage = spyOn((env.component as any).dialogService, 'message').and.callThrough(); + env.setupDialogRef(); + const textDocId = new TextDocId('project02', 40, 1, 'target'); env.deleteText(textDocId.toString()); expect(dialogMessage).toHaveBeenCalledTimes(1); @@ -3666,6 +3668,8 @@ describe('EditorComponent', () => { // SUT const dialogMessage = spyOn((env.component as any).dialogService, 'openGenericDialog').and.callThrough(); + env.setupDialogRef(); + expect(env.copyrightBanner).not.toBeNull(); env.copyrightMoreInfo.nativeElement.click(); tick(); @@ -4736,6 +4740,12 @@ class TestEnvironment { this.addProjectUserConfig(user5Config as SFProjectUserConfig); } + setupDialogRef(): void { + const mockDialogRef = jasmine.createSpyObj('MatDialogRef', ['afterClosed']); + mockDialogRef.afterClosed.and.returnValue(of(undefined)); + spyOn((this.component as any).dialogService.matDialog, 'open').and.returnValue(mockDialogRef); + } + getProjectUserConfigDoc(userId: string = 'user01'): SFProjectUserConfigDoc { return this.realtimeService.get( SFProjectUserConfigDoc.COLLECTION, From f9d5bddb17aa06852dfc0937b70851bc297f1e56 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 19 Dec 2024 07:17:25 +0700 Subject: [PATCH 3/3] PR comments --- .../src/xforge-common/retrying-request.service.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts index b69f36fff5..b33bec9499 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/retrying-request.service.ts @@ -1,5 +1,5 @@ import { Inject, Injectable } from '@angular/core'; -import { lastValueFrom, Observable, Subject } from 'rxjs'; +import { firstValueFrom, Observable, Subject } from 'rxjs'; import { filter, take } from 'rxjs/operators'; import { CONSOLE, ConsoleInterface } from './browser-globals'; import { CommandErrorCode, CommandService } from './command.service'; @@ -96,7 +96,7 @@ export class RetryingRequest { private async invoke(options: FetchOptions): Promise { while (!this.canceled && this.status !== 'complete') { - const online = await lastValueFrom(this.online$.pipe(take(1))); + const online = await firstValueFrom(this.online$); if (online !== true) { this.status = 'offline'; await this.uponOnline(); @@ -124,12 +124,7 @@ export class RetryingRequest { } private async uponOnline(): Promise { - await lastValueFrom( - this.online$.pipe( - filter(isOnline => isOnline), - take(1) - ) - ); + await firstValueFrom(this.online$.pipe(filter(isOnline => isOnline))); } private isNetworkError(error: unknown): boolean {