Tips for utilizing the keyword 'this' within a Promise

Seeking assistance with resolving an issue involving an undefined error when attempting to make an http request within a Promise function. The error occurs due to this.http.post being undefined, indicating that there is an issue with accessing this properly.

If anyone has insights or suggestions on how to resolve this issue, your help would be greatly appreciated!

doUpload(files: Array<File>): Promise<Array<UploadResult>> {
    console.log(files);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        let result: Array<UploadResult> = [];
        for (let file of files) {
          this.http
            .post(this.APIURL + "/image/upload/markdown", file)
            .subscribe((data) => {
              console.log(data);
            });
          result.push({
            name: file.name,
            url: `https://avatars3.githubusercontent.com/${file.name}`,
            isImg: file.type.indexOf("image") !== -1,
          });
        }
        resolve(result);
      }, 3000);
    });
  }

The encountered error message:

> TypeError: undefined is not an object (evaluating 'this.http.post')  
> (anonymous function) — sensor-edit.component.ts:308  
> onInvokeTask — core.js:39680  
> runTask — zone-evergreen.js:168  
> invokeTask — zone-evergreen.js:465  
> timer — zone-evergreen.js:2650

This error originates from the constructor, where this.http is defined:

constructor(
    private fb: FormBuilder,
    private route: ActivatedRoute,
    private api: ApiService,
    private _routerService: Router,
    private errorService: ErrorModalService,
    private sanitizer: DomSanitizer,
    private http: HttpClient
  ) {}

The doUpload function is invoked in the HTML as follows:

<div class="container well come-space">
          <md-editor formControlName="markdown" name="Content" [height]="'400px'" [upload]="doUpload">
          </md-editor>
</div>

Answer №1

To be honest, I fail to see the practicality of converting the Observable to a Promise in this scenario. It seems that by doing so, multiple subscriptions are being created unnecessarily which could potentially remain open. Instead, my recommendation would be to utilize the RxJS forkJoin method to execute multiple observables concurrently within a single subscription.

Here is an alternative approach:

import { forkJoin, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

doUpload(files: Array<File>): Observable<Array<UploadResult>> {
  return forkJoin(                                  
    files.map((file: any) =>                       
      this.http.post(
        this.APIURL + "/image/upload/markdown", 
        file
      ).pipe(
        map((data: any) => ({                       
          name: file.name,
          url: `https://avatars3.githubusercontent.com/${file.name}`,
          isImg: file.type.indexOf("image") !== -1,
        }))
      )
    )
  );
}

You can then subscribe to the function like so:

this.doUpload(files).subscribe({
  next: (response) => console.log(response),
  error: (error) => console.log(error)
});

Update

As mentioned in the comments, it's not advisable to use my solution with the <md-editor>'s @Input() upload parameter. You should implement your own version of doUpload() and include the following snippet in your component's constructor.

constructor() {
  this.doUpload = this.doUpload.bind(this);
}

This information was sourced from ngx-markdown-editor's documentation.

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

Having issues with downloading a Zip file from the axios post API in React due to receiving an invalid file

Trying to extract downloaded file, but getting error const extractDownloadedFile = async (ids: number) => { try { const response = await axios .post(`/api/folders/${folderDetails.id}/download`, { resources: ids, }) .then( ...

Setting a property with a generic type array: Tips and tricks

Currently, I am working on implementing a select component that can accept an array of any type. However, I am facing some challenges in defining the generic and where to specify it. My project involves using <script setup> with TypeScript. Here is ...

The back-end is not receiving the HTTP Get call, even though the URL is functional in the browser. The error message states that the JSON is

The backend function is functioning properly as both Postman and Swagger are able to call it without any issues. I decided to capture the URL string displayed in the error message and pasted it into a browser. Surprisingly, it successfully reached the bac ...

Using JavaScript to place a particular tag at a designated position

I have a string that looks like this: var txtstr='<p>Text 1</p><p>&nbsp;</p><p>Text &nbsp;2</p><p>&nbsp;</p><p>Text 3&nbsp;</p>'; I have an <img src=..../> tag and ...

Creating a responsive and engaging user interface can be achieved by adding animation effects to

I am currently utilizing Ionic 2+ and attempting to add animation to an image using animate.css. Upon initial loading, the image should display a rubberBand animation, and with each click, it should switch to a bounce animation. The rubberBand animation wo ...

Dynamic Angular form with nested elements

Need help creating a nested form following the example from angular.io documentation: https://stackblitz.com/angular/pbdkbbnmrdg The objective is to include two DropdownQuestion elements from question.service.ts within a child formgroup called "details", ...

Angular 7 - Issue with Loading Material Component Styles

In the midst of my latest Angular 7 project, I decided to incorporate the out-of-the-box material components. Unfortunately, there seems to be a hiccup with some of the CSS not being applied and pinpointing the cause is proving to be an elusive task. For ...

Verify if the array entries match

Within my select element, I populate options based on an array of values. For example: [{ name: 'A', type: 'a', }, { name: 'B', type: 'b', }, { name: 'B', type: 'b', }, { name: &apos ...

TypeScript fails to acknowledge an exported enum

Currently utilizing TypeScript version 2.5.3 along with Angular 5. I have an enum defined in a separate file as follows: export enum eUserType { Driver = 1, Passenger = 2, User = 3 } To import and use it in another ts file, I do the following: i ...

Having trouble moving to a different component in Angular?

In my application, I am facing an issue with navigating from List to Details component by passing the ID parameter. It seems that there is no response or error when attempting to call the relevant method. Below, you can find the code snippets related to th ...

Encountering type errors in React+Typescript while dynamically setting values in the change handler

I am currently working on dynamically generating a form based on an array of objects. The objective is to allow users to create accounts dynamically by clicking the Add User button and then submit the complete state object of users to the backend. Encoun ...

Creating custom designs for Material UI components

Although not a major issue, there is something that bothers me. I am currently using react, typescript, and css modules along with . The problem arises when styling material ui components as I find myself needing to use !important quite frequently. Is th ...

Using a pipe filter to implement a search feature in an Ionic search bar

Hey everyone, I'm facing a little issue here. I created a pipe filter to sort through some data, but now I need to include two more filters and I'm not sure how to go about it within this pipe. Below is an example of the pipe I have created: ...

Issue: StaticInjectorError(DynamicTestModule)[FilterOptionsComponent -> Environment]:

While testing my app, I encountered an error that stated: "PhantomJS 2.1.1 (Linux 0.0.0) FilterOptionsComponent should clean fields when click in the clean button FAILED Error: StaticInjectorError(DynamicTestModule)[FilterOptionsComponent -> Environ ...

Problem with Packaging Angular and Spring Boot Applications

My current project structure consists of a spring boot angular project +--app-ui |--+--src |--+--dist |--app-backend |--+--src |--+--+--main |--+--+--+--resources |--+--+--+--+--static |--+--+--+--java The app-ui directory contains the Angular 6 code, wh ...

Rendertron always renders base routes as empty

I'm running into an issue while trying to use rendertron via an Apache proxy - all the base routes are showing up as "null." Could this be due to a configuration error on my part? Any help would be greatly appreciated. The Rendertron service is curre ...

Setting the [required] attribute dynamically on mat-select in Angular 6

I'm working on an Angular v6 app where I need to display a drop-down and make it required based on a boolean value that is set by a checkbox. Here's a snippet of the template code (initially, includeModelVersion is set to false): <mat-checkbo ...

Error: Unable to locate the tslint command

After attempting to utilize tslint --fix, I encountered the error message bash: tslint: command not found.... To install tslint, I ran the following command: yarn global add tslint typescript. The operating system on my machine is Centos 7. ...

Reduce the size of a container element without using jquery

In my Angular application, I have structured the header as follows: -- Header -- -- Sub header -- -- Search Box -- -- Create and Search Button -- -- Scroll Div -- HTML: <h1> Header </h1> <h3> Sub header </h3> <div class="s ...

Issues with expanding all nodes in the Angular Treeview function by Nick Perkins in London are causing difficulties

Currently utilizing the angular treeview project found here: https://github.com/nickperkinslondon/angular-bootstrap-nav-tree After examining the functionality, it seems that this treeview is lacking search capabilities. To address this limitation, I deci ...