Alert once all observables have finished

I have a collection of observables, each representing a file that needs to be uploaded using an HTTP request.

My objectives are:

  1. To emit an event for each successfully uploaded file, which will be handled in the parent component.
  2. To notify when all files have been uploaded and all observables are completed.

I began with the following code snippet:

this.isUploading$ = Observable.of(true);

const source$ = Observable.from(files)
    .concatMap(file => this.uploadSingleFile(file));

source$.subscribe(data => this.onSuccess.emit(data));

The Observable isUploading$ indicates that the upload process has commenced and is utilized in the HTML to display a spinner based on its state.

The Observable source$ represents the series of file upload operations as it calls the method this.uploadSingleFile(file) and expects an Observable<Response>.

This code effectively uploads all files and triggers this.onSuccess.emit(data) upon completion of each observable.

Now my question is: How can I change the value of this.isUploading$ to false once all tasks are finished?

UPDATE:

I aim to achieve similar functionality without having to set a variable in the onCompleted function. For example:

source$.subscribe(data => this.onSuccess.emit(data),
                  err => console.log(err),
                  () => this.isUploading = false );

I wish to extract two observables and subscribe to them at a later convenience.

Answer №1

If you are looking to execute all of these observables simultaneously, using concatMap will not achieve the desired outcome. Instead, you can utilize the do and forkJoin operators for this purpose.

forkJoin can be compared to Promise.all but tailored for observables.

do serves as a method to intercept the values flowing through an observable, allowing for side effects to be performed.

Therefore:

const arrayOfObservables = [observable1, observable2, observable3];

Observable.forkJoin(
  arrayOfObservables.map((obs, i) => obs.do({
    next(value) { console.log(`Observable ${i} emitted: ${value}`); },
    complete() { console.log(`Observable ${i} has completed`); }
  }))
)
.subscribe(values => console.log('all tasks finished with', values))

Answer №2

What is the reason for making isUploading an observable? Personally, I would approach it in the following way:

this.isUploading = true;
const source$ = Observable.from(files)
    .concatMap(file => this.uploadSingleFile(file));

source$.subscribe(data => this.onSuccess.emit(data),
                  err => console.log(err),
                  () => this.isUploading = false );

Answer №3

To handle this situation, consider utilizing a Subject:

private uploadStatus = new Subject<boolean>();

You can then update the status like so:

this.uploadStatus.next(false);
this.uploadStatus.complete();

Additionally, you can use the combineLatest operator to synchronize the completion of all tasks:

const allTasks$ = Observable.combineLatest(tasks$);
allTasks$.subscribe(result => {
    this.uploadStatus.next(false);
    this.uploadStatus.complete();
}

This approach should meet your requirements effectively.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Increase the size of the NativeScript switch component

Here is the code I am working with: .HTML <Switch style="margin-top: 10" (checkedChange)="onFirstChecked1($event)" row="0" col="1" horizontalAlignment="center" class="m-15 firstSwitchStyle"></Switch> .CSS .firstSwitchStyle{ width: 30%; ...

Challenges faced when incorporating ng-content within Angular components

I am facing a specific issue where I need to pass code from a file containing a component to its child component. My initial approach was to use ng-content, but unfortunately, this method did not work as expected. I am unsure if the ng-content usage is inc ...

The 'asObservable' property is not present on the type '() => any'.ts(2339)

Error: Property 'asObservable' does not exist on type '() => any'.ts(2339) Error: Property 'subscribe' does not exist on type 'Subscription'. Did you mean 'unsubscribe'?ts(2551) Error: Property 'sub ...

Tips for combining Angular 2 with a current J2EE Spring project and deploying them on the same PORT

I currently have a project with Spring on the back-end and AngularJS 1 on the front-end. When I start the Spring server, it only opens one port for me: 8080 which allows me to access REST APIs and the AngularJS front-end components. https://i.stack.imgur. ...

What could be the reason for a property going unnoticed during the iteration of a list?

The Scenario There is a class named myClass: export class myClass { name: string; age: number; city: string; } and another class called people: export class people { name: string; age: number; } In the component.ts, a variable list ...

What could cause my arguments to "not align with any signature" of console.log?

Here is a basic class example: export class Logger { constructor(private name: string) {} debug(...args: any[]) { console.debug(...args) } log(...args: any[]) { console.log(...args) } } Despite being able to pass anything to console.l ...

Retrieve the stored information from a variable

Can anyone help me with a coding issue I'm facing? I have a constant called data, which contains two values - prediction and probability. What is the best way to access and retrieve both values? type ML = { prediction: string; probability: num ...

Having trouble accessing @ViewChildren from the parent component

I've been facing an issue while attempting to control the child instances of a component and I can't seem to bypass this particular error. I've been referring to solutions provided on this specific thread. The main component Sequence houses ...

Resolving "SyntaxError: Unexpected identifier" when using Enzyme with configurations in jest.setup.js

I'm currently facing an issue while trying to create tests in Typescript using Jest and Enzyme. The problem arises with a SyntaxError being thrown: FAIL src/_components/Button/__tests__/Button.spec.tsx ● Test suite failed to run /Users/mika ...

Step-by-step guide to developing an Angular 2+ component and publishing it on npm

I need assistance with creating an AngularX (2+) component and getting it published on npm. My objective is to publish a modal component I developed in my current Angular App, though currently, I am focusing on creating a <hello-world> component. It ...

Using a snippet of HTML code from one Angular component in another component

Is it possible to use a specific div element from one Angular component in another component? main component.html <html> <div1> some elements </div1> <div2> some elements </div2> In the child ...

Having difficulty compiling Angular with Bootstrap

I have encountered an error while attempting to start a project with Angular: "ERROR in multi ./src/styles.css ./node_modules/bootstrap/dist/css/bootstrap.min.css Module not found:" Here are the dependencies: "dependencies": { "@angular/animation ...

"Within Angular 2+, the attribute referenced is not recognized as a valid property, even though it is explicitly defined within the @Input

The main goal here is to increase the vertical pixel count. <spacer [height]="200"></spacer> Initially facing an issue where an error message states that height is not a recognized attribute of spacer. To address this problem, I set up the fo ...

Exploring the wonders of accessing POST request body in an Express server using TypeScript and Webpack

I am currently working on a Node and Express web server setup that utilizes Webpack, along with babel-loader and ts-loader. Let's take a look at some key portions of the code: webpack-config.js: const path = require("path"); const nodeExte ...

Encountering Webpack issues following the transition to Next 13

Since updating Next to version 13, we've encountered issues with our application not building properly. It appears that webpack is having trouble with imports, exports, and potentially typescript. ../../libs/queries/src/lib/groq/searchFaq.ts Module pa ...

Using React with Typescript: How to pass a function as a prop to a child component and call it from within

I am trying to pass a function as a prop to a child component so that the child can call it. Here is my parent component: interface DateValue { dateValue: string; } const Page: React.FC = () => { const dateChanged = (value: DateValue) => { ...

Create an observable array that contains both outer and inner response properties within an Angular application

How can I create an Observable array in Angular by making API calls based on the response of another API call, which returns an array of elements? For example: queryThatReturnsArray().pipe( switchMap((outerResponse) => { return forkJoin(out ...

What is the process for implementing a datepicker search feature on an Angular14 Dashboard? Additionally, how can users filter search values by simply selecting a date on the date

How can I implement a datepicker search feature in my Angular14 Dashboard? Can I filter search results by simply clicking on a date in the datepicker? Html: <input type="date" style="width: 100%; height: 34px" (change)="SendDat ...

Can a file be transferred from the private path to the document directory?

I wrote this code using the captureVideo() method from the Ionic Native MediaCapture plugin. Here is the file path I obtained: /private/var/mobile/Containers/Data/Application/95DB5A64-700B-4E3D-9C2C-562C46520BEC/tmp/52515367181__BBC39D42-69EC-4384-A36F-7 ...

Replacing URLs in Typescript using Ionic 3 and Angular

Currently facing some difficulties getting this simple task to work... Here is the URL format I am dealing with: https://website.com/image{width}x{height}.jpg My objective is to replace the {width} and {height} placeholders. I attempted using this func ...