Home > database >  RxJS from() operator never completes
RxJS from() operator never completes

Time:01-05

I'm trying to perform metadata update in the sharepoint list. In the component I have:

this.datasetService.updateMetadata(oldDatasetName, projectMetadata).subscribe(() => {
   this.onCompleted('DownloadDataset.Updated');
}, error => this.onError(error, 'DownloadDataset.UpdateError'));

Then in the service:

updateMetadata(oldDatasetName: string, metadata: ProjectDatasetModel): Observable<boolean[]> {
    const filterString = `DataSetName eq '${oldDatasetName}'`;
    return this.graphService.getFilteredListItems(ResourceNames.PROJECT_DATASET_LIST_NAME, filterString).pipe(switchMap(items => from(items).pipe(mergeMap(item => {
        const updated = { ...item, DataSetName: metadata.datasetName, DataSetDescription: metadata.datasetDescription };
        return this.graphService.updateListItem(ResourceNames.PROJECT_DATASET_LIST_NAME, updated.Id, updated);
    }), toArray(), tap(() => console.log("Update completed")))));
}

GraphService:

public getFilteredListItems(listTitle: string, filter: string): Observable<any[]> {
    const sub$ = new Subject<any[]>();
    this.configureSharepointToken().subscribe(configured => {
        sp.web.lists.getByTitle(listTitle).items.filter(filter).get().then((items: any[]) => {
            sub$.next(items);
        });
    });
    return sub$.asObservable();
}

public updateListItem(listTitle: string, itemId: number, listItem: any): Observable<boolean> {
    const sub$ = new Subject<boolean>();
    this.configureSharepointToken().subscribe(configured => {
        sp.web.lists.getByTitle(listTitle).items.getById(itemId).update(listItem)
            .then(iar => {
                sub$.next(true);
            });
    });

    return sub$.asObservable();
}

My issue is that if there are items to be updated, update does happen and I can the new metadata, but tap() never happens. Any suggestions?

CodePudding user response:

In getFilteredListItems and updateListItem you're return a subject that never completes. The toArray operator won't execute until the subjects are closed.

The whole business of creating subjects and returning them is superfluous. If configureSharepointToken returns an observable, then just switchMap from those streams. Super fun fact: since the get methods return promises, they will work in any operator that accepts observables.

public getFilteredListItems(listTitle: string, filter: string): Observable<any[]> {
  return this.configureSharepointToken().pipe(
    switchMap(() =>  sp.web.lists.getByTitle(listTitle).items.filter(filter).get())
  );
}

public updateListItem(listTitle: string, itemId: number, listItem: any): Observable<boolean> {
  return this.configureSharepointToken().pipe(
    switchMap(() => sp.web.lists.getByTitle(listTitle).items.getById(itemId).update(listItem)),
    mapTo(true)
  );
}

One note, the first operator might need to be added at the beginning of the pipes in case configureSharePointToken stays open. Personally it seems strange that it'll have more than one emission.

  •  Tags:  
  • Related