Changes are reflected in the service variable, but they are not updating in the component

I am facing an issue with a variable that is supposed to track the progress of image uploads. The variable seems to be working fine, but it remains undefined in my component.

Upload Service method

 uploadProfilePic(url:string, user_id:string, image:any) {
    this.imgComp.compress(image)
      .pipe(take(1))
      .subscribe(compressedImage => {
        try {
          var formdata = new FormData();
          formdata.append("profile_photo", compressedImage, compressedImage.name);
          formdata.append("user_id", user_id);
          this.http.put(url, formdata, { reportProgress: true, observe:'events' }).subscribe( event => {
            if(event.type === HttpEventType.UploadProgress) {
              this.upload_progress = Math.round(event.loaded / event.total * 100)
              console.log(this.upload_progress)
            } else if(event.type === HttpEventType.Response) {
              this.toast.showToast(`Your profile pic has been updated!`)
              //this.upload_progress = undefined
              console.log(this.upload_progress)
              //setTimeout(function(){ location.reload() }, 4000)
            }      
          })
        } catch (error) {
          this.toast.showToast(error.message)
        }
      })
  }

I'm using an image compressor service, but I don't think that's the cause of the problem.

Upload Service constructor

constructor(private http: HttpClient, public env: EnvService, private toast: Ion_Toast, private imgComp: ImageCompressorService) { }

Then I call it in my component:

constructor(
    private modalController: ModalController,
    public imgUploader: ImageUploadService
  ) { }

To display in the document:

<ion-progress-bar value="{{imgUploader.upload_progress/100}}"></ion-progress-bar>
<h1>{{imgUploader.upload_progress}}</h1>

I have also verified that the service is included in the app-module and everything appears to be correct.

App-Module

providers: [
    ImageUploadService
  ],

I'm not sure if I should also declare the compressor in the providers section, maybe that could resolve the issue.

EDIT

My input doesn't directly use the upload method, it first goes through a select image method.

ImageUploadService

upload_progress: number

selectProfilePic(event, user_id) {
    this.uploadProfilePic(`${this.env.API_URL}/users/update_profile_image`, user_id, <File>event.target.files[0])
  }

Answer №1

Directly accessing service values in components is not recommended. This could be the reason why it's not functioning as expected.

An alternative approach would be to utilize an observable in your service that you can subscribe to within your component.

Here's an illustration:

class Component {
  uploadProgress: number;
  
  constructor(
    imgUploader: ImageUploadService
  ) {}

  onUpload() {
    this.imgUploader
      .uploadProfilePic() // Should return an observable of the progress value
      .subscribe(progress => (this.progress = progress));
  }
}

class ImgUploaderService {
 uploadProfilePic(url:string, user_id:string, image:any) {
    const uploadProgress = new BehaviorSubject(0);
    
    this.imgComp.compress(image)
      .pipe(take(1))
      // ... subscribe and update the progress in your behavior subject

    return uploadProgress.asObservable();
  }
}

For more information on BehaviorSubjects, refer to: https://rxjs-dev.firebaseapp.com/api/index/class/BehaviorSubject. You may require methods such as asObservable(), next(), error(), and complete().

If you need further clarification or have any inquiries, feel free to ask.

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

Exploring the depths of Angular8: Utilizing formControlName with complex nested

After dedicating numerous hours to tackle this issue, I finally came up with a solution for my formGroup setup: this.frameworkForm = this.formBuilder.group({ id: [null], name: ['', Validators.required], active: [true], pa ...

I am encountering an "ERROR null" message in my Angular application within VSCode. How can I identify the root cause of this issue?

https://i.sstatic.net/bIZcK.png After compiling my Angular v17 project, I encountered error messages in the terminal that do not provide any specific reference or link to the issue. Surprisingly, the web browser console does not display any errors either. ...

TypeError thrown by Mapbox markers

Looking to incorporate markers into my map using Mapbox. Below is the Angular TypeScript code I am working with: export class MappViewComponent implements OnInit { map: mapboxgl.Map; lat = 41.1293; lng = -8.4464; style = "mapbox://styles/mapb ...

Error with the type of CanvasGradient in the NPM package for converting text to image

I attempted to generate an image using a specific text by utilizing npm's text-to-image package, but encountered an error during typescript compilation. The errors I encountered upon running the typescript compilation command are related to files with ...

Creating an Angular 2 application within a Cordova project

I've been on the hunt for resources that break down using Angular 2 in a Cordova app, but it seems like there's a lack of straightforward explanations out there. For example, once I create a Cordova app with: cordova create sampleApp, should I na ...

The enigma of the mysterious karma provider error

As a newcomer to unit testing in JavaScript, AngularJS, and Karma, I have successfully written passing tests for controllers. However, when trying to test services, I encountered an error: Unknown provider <- nProvider <- User. The User service is th ...

Angular 2 event emitter falling behind schedule

I am currently utilizing Angular 2 beta 6. The custom event I created is not being captured import {Component, OnInit, EventEmitter} from 'angular2/core'; import {NgForm} from 'angular2/common'; import {Output} from "angular2/core" ...

Is the Prisma model not reachable through Prisma Client?

I'm currently attempting to retrieve a specific property of a Prisma model using Prisma Client. The model in question is related to restaurants and includes a reviews property that also corresponds with a separate Review model. schema.prisma file: // ...

Beta 8 of Angular Material 2 is causing MdDialog.afterAllClosed to return an undefined result instead of the expected data

I am currently facing an issue where the result from the dialog component's close method is returning as undefined. Could this be a bug present in angular material 2 beta 8? I have searched extensively online but have not been able to find any inform ...

Encountering Issues with Docusign Authorization Code in Fetch Request, but Successfully Working in Postman

Yesterday, I attempted to access Docusign's API in order to authenticate a user and obtain an access token. However, when trying to fetch the access token as outlined here, I encountered an "invalid_rant" error. I successfully obtained the authorizat ...

Utilizing a string variable as a property name for dynamic typing

I am looking to dynamically create a type with a property name based on specified parameters. Although I can successfully create the object, I am facing challenges when trying to create the actual type. This dynamic type creation is essential for compositi ...

Showing dynamic icons in Angular 2 applications

My goal is to dynamically load a part of my website, specifically by using icon classes defined in the interface like this: import { OpaqueToken } from "@angular/core"; import {IAppConfig} from './app.interface' export let APP_CONFIG = new Opaq ...

Ways to verify if TypeScript declaration files successfully compile with local JavaScript library

I have recently updated the typescript definitions in HunterLarco/twitter-v2, which now follows this structure: package.json src/ twitter.js twitter.d.ts Credentials.js Credentials.d.ts My goal is to verify that the .js files correspond correctly ...

Integrating Video.js with the latest version of Angular, Angular

Looking to integrate Video.js into my Angular 6 project and retrieve the current play time and video duration. I came across the @types/video.js library but unsure of the correct way to utilize it. Any advice on how to properly implement it? ...

"Adjusting the position of an Ionic Menu on-the-fly

As I strive to update the Ionic 3 Menu side dynamically when the user changes the language, a challenge arises for RTL languages where the menu needs to be on the right instead of the default left. To tackle this issue, I have subscribed to the TranslateS ...

The default behavior of Angular-Keycloak does not include automatically attaching the bearer token to my http requests

I'm currently working on integrating keycloak-angular into my project, but I'm facing an issue with setting the bearer token as the default for my HTTP requests. "keycloak-angular": "9.1.0" "keycloak-js": "16.0 ...

`How can I extract HTMLElements from slots in vue3?`

When attempting to develop a Layer component, I encountered some challenges. Here is the code: // Wrapper.vue <template> <slot v-bind="attrs"></slot> </template> <script lang="ts" setup> import { defi ...

Determining the optimal size for the thumb on a mat slider

Currently, I have incorporated a mat slider into my Angular application. For reference, you can view the Stackblitz link here: https://stackblitz.com/edit/angular-material-custom-slider?file=app%2Fslider-overview-example.ts The issue I am encountering is ...

Issues arise in TypeScript when attempting to assign custom properties to a Vue component

I was working on implementing Vue middleware and faced an issue while trying to add a custom property to one of my components in Vue. Here's the code snippet: middleware.js: import { VueConstructor } from 'vue/types'; function eventPlugin(v ...

Which TypeScript AsyncGenerator type returns a Promise?

I am currently in the process of assigning a return type to the function displayed below: async function *sleepyNumbers() { // trying to determine TypeScript type let n = 0; while (true) { yield new Promise(resolve => resolve(n++)); ...