Accessing the value of an Observable variable without triggering the assigned function to run again

Currently, I have a function in my Angular component that is executed whenever I need to upload a list of files.

I aim to monitor the upload progress to empty the file list and keep track of the upload progress for a progress bar display.

The issue I am facing is that when I access the value of uploadProgress, it triggers

this.pictureService.upload(this.selectedFiles)
twice, resulting in the files being uploaded twice.

This is how my current function looks like:

uploadImages() {
  // Upload picture and save progress as an observable
  const uploadProgress: Observable<HttpEvent<HttpUploadProgressEvent>> = this.pictureService.upload(this.selectedFiles);

  // Show snackbar with observable for progress bar
  this.snackBar.openFromComponent(UploadProgressComponent, {
    data: { uploadProgress },
  });

  // Wait for the upload to finish and then reset selected files and preview URLs
  uploadProgress.subscribe((event: HttpUploadProgressEvent) => {
    if (event.loaded === event.total && event.loaded !== undefined) {
      this.selectedFiles = null;
      this.previewUrls = [];
    }
  });
}

Answer №1

Each time you invoke .subscribe, the observable is triggered (refer to this link).

If you are using this within the openFromComponent function, it's advisable not to call .subscribe again. You can use a method like this instead:

uploadImages() {
// Upload picture and track progress with observable
const uploadProgress: Observable<HttpEvent<HttpUploadProgressEvent>> = this.pictureService.upload(this.selectedFiles);

// Generate snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
  data: {
    uploadProgress.pipe(tap((event: HttpUploadProgressEvent) => {
      if (event.loaded === event.total && event.loaded !== undefined) {
        this.selectedFiles = null;
        this.previewUrls = [];
      }
    }))
  }
})

}

Answer №2

Following Martin's recommendation, I made a modification by adding .pipe(share()) to the end of my constant, resulting in the desired functionality.

This is how my code now appears:

uploadImages() {
  // Upload image and track progress using an observable
  const uploadProgress = this.imageService.upload(this.selectedFiles).pipe(share());

  // Display snackbar with progress bar based on the observable
  this.snackBar.openFromComponent(UploadProgressComponent, {
    data: { uploadProgress },
  });

  // When upload is complete, reset selected files and preview URLs
  uploadProgress.subscribe((event: HttpUploadProgressEvent) => {
    if (event.loaded === event.total && event.loaded !== undefined) {
      this.selectedFiles = null;
      this.previewUrls = [];
    }
  });
}

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

The TypeScript compiler does not allow a 'number' type to be assigned to 0, 10, or 20, even when the number itself is 0

When testing out my code snippet on the playground for Typescript, an error appears on line 24. I discovered that the issue can be resolved by explicitly casting commands back to <IPlan[]>, but I wonder why this extra step is necessary. Property &a ...

Steps for updating a server component after redirectionWould you like to know how

One of my server components fetches and displays data only when the user is authorized: function CheckAuthorization() { const isAuthenticated = // check if user is authorized return ( <div> {isAuthenticated ? ( <DisplayAutho ...

Sort through the files for translation by utilizing a feature within Typewriter

I am looking to implement Typewriter in a project that involves translating many C# files into TypeScript using WebEssentials. Is there a way to configure the template so that only class files containing a specific attribute are translated in this mann ...

Explore a vast array of items in a collection

I have a massive collection of various objects that I need to sift through. With over 60,000 elements, the search operation can sometimes be painfully slow. One typical object in this array has the following structure: { "title": "title" "company": ...

Issue with refreshing Angular2 page causing it to not load

Encountering an issue here. When clicking on the anchor tag in my index <a href="/month/1">Month</a> the app fails to load, but when clicking on the anchor tag in my component <a routerLink="/month/1"> Month</a> the app success ...

Setting up a passthrough for a directory of external resources in Angular

Issue: I am currently facing a challenge with a project that requires accessing photos from a system that has recently been updated from AngularJs to Angular 16. Initially, we were able to serve these photos from a virtual directory like https://myawesom ...

Resolving search box setup problem in PrimeNG dataView

I am working on integrating p-dataView with Angular 5 but encountering an error Cannot read property 'split' of undefined at DataView.filter Despite checking the documentation, I have been unable to find a solution to this issue. It seems lik ...

Tips for incorporating multiple services within a single Angular component

Issue found in src/app/header1/header1.component.ts:3:30 - TypeScript error TS2306: The file 'F:/Angular-projects/lawyer-listing/src/app/services/state.service.ts' is not recognized as a module. 3 import { StateService } from '../services/st ...

Error encountered in Angular testing when component fixture becomes undefined after test execution with subcomponents in version 4.0.0-beta.8

I'm facing a strange issue while testing my Angular code. Setting things up goes smoothly, but when I define subcomponents in the TestBed.configureTestingModule declaration, things start to break. The initial test within a describe block works fine, b ...

Why is it that my service in the Angular project doesn't fetch data after I make changes and reload the page?

When a user selects a customer, I have a method that fetches the customer's ID from the database and saves it to local storage. However, if I make changes to my code and refresh the page after selection, it doesn't fetch the customer ID. How can ...

Updating the background color of the side menu in Ionic 4

Wanting to customize the background color of the side sliding menu in my ionic 4 project Here is the code I am using: <ion-app> <ion-split-pane> <ion-menu> <ion-header> <ion-toolbar color="medium"> ...

Showing the Enum name rather than the value in an Angular HTML template for a bound Typescript Interface

After retrieving an array of objects with various properties from a .NET Controller, I am utilizing the following Typescript code: import { Component, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Co ...

What is the best way to communicate an event occurring within the ng-content to the reusable parent component in Angular?

I am looking to create a versatile dropdown component in Angular that can display different content such as a list or a tree. Essentially, I want to be able to extract the selection label that triggers the dropdown to open and close upon clicking. dropdow ...

What steps can be taken to resolve the TS5023 error that arises when including "allowImportingTsExtensions" in the tsconfig.json file?

While working on my React project, I've encountered a specific error that reads: Could not parse tsconfig.json. Please ensure it contains valid JSON syntax. Details: error TS5023: Unknown compiler option 'allowImportingTsExtensions'. I tr ...

Creating TypeScript Unions dependent on a nested object's property

I want to create a Union Type that is dependent on a nested property within my object. Take a look at the example provided below: type Foo = { abilities: { canManage: boolean } } type Bar = { abilities: { canManage: boolean ...

Discovering the clicked element within a QueryList<ElementRef> in Angular

Having a ElementRef(QueryList) of a group of dynamically created Table cells (td html elements) using ViewChildren, I have successfully debugged and verified the availability of the element set. When clicking on a specific td html element, a function is c ...

Troubleshooting Issue: Relative Paths Fail to Work with routerLink in Angular 6

I seem to be encountering a problem with the Angular app I'm currently developing. It appears that when using relative paths with routerLink throughout the application, it fails to work properly. There are no errors thrown and the navigation does not ...

The expiration of the Gitlab CI/CD cache leads to the failure of the build process

I have an AWS CDK application in TypeScript and a simple GitLab CI/CD pipeline with 2 stages for deployment: image: node:latest stages: - dependencies - deploy dependencies: stage: dependencies only: refs: - master changes: - ...

What is the best way to make one element's click event toggle the visibility of another element in Angular 4?

Recently diving into Angular, I'm working on a feature where users can toggle the visibility of a row of details by simply clicking on the item row. The scenario involves a table displaying log entries, each with a hidden row underneath containing spe ...

When defining a class property in TypeScript, you can make it optional by not providing

Is there a way to make a property on a Class optional without it being undefined? In the following example, note that the Class constructor takes a type of itself (this is intentional) class Test { foo: number; bar: string; baz?: string; construc ...