Search code examples
arraysangulartypescripthttpresponseangular-pipe

How do I loop through an Angular HTTP Response?


I'm a beginner in Angular trying to learn the ins and outs. I'm uploading a file and making a call to an API which validates the file. In the response is a list of JSON validation errors that come back based on some values of the file.

I'm attempting to loop through these responses and display them to the user, but I'm a bit lost.

I've tried combinations of map/pipe/subscribe and it seems like the subscribe function is working the best for me and is the only way I can see what the values being sent are. But I'm unsure of how to display the actual values instead of [Object, Object].

I'm also trying to learn the best practices so I'm unsure if I am going down the right path here.

Response object

error list expanded

error list expanded too

enter image description here

What should I be doing after my POST code is returned?

this.httpClient.post(this.PartsAPIURL, formData, { headers: headers })
      .subscribe(event => {
        this.submissionResult = event;
        console.log(this.submissionResult);
        //what to do here?
    });

And how do I combine it with the HTML response?

<p>{{submissionResult}}</p>

Here are some of the failed snippets of code I've been trying

Attempt to assign to an array variable

this.httpClient.post(this.PartsAPIURL, formData, { headers: headers })
      .subscribe(event => {
        //fails because the validationErrors and subcategoryErrors are not initialized properly
        this.UploadResponse.validationErrors = event["validation_errors"];
        this.UploadResponse.subcategoryErrors = event["subcategory_errors"];
        console.log(this.UploadResponse.validationErrors);
        console.log(this.UploadResponse.subcategoryErrors);
    });

Doesnt return anything - no console statements at all

this.httpClient.post<PartsUploadResponse>(this.PartsAPIURL, formData, { headers: headers })
      .pipe(
        map(data => {
          console.log(data)
          this.UploadResponse.subcategoryErrors = data['subcategoryErrors'];
          this.UploadResponse.validationErrors = data['validationErrors'];
          console.log(this.UploadResponse);
        }));

Response class

export class PartsUploadResponse {
  public validationErrors: any;
  public subcategoryErrors:any;

}

Thank you for the help!


Solution

  • Let's define your response type so the typescript compiler can show you any mistakes:

    type ErrorResponse = {
      subcategory_errors: ErrorList[],
      validation_errors: ErrorList[]
    }
    
    type ErrorList = {
      sheet: string,
      errors: string[]
    }
    

    We can assign the error lists to local variables like so:

    subcategoryErrors: ErrorList[] = [];
    validationErrors: ErrorList[] = [];
    
    ngOnInit() {
      this.httpClient.post(this.PartsAPIURL, formData, { headers: headers })
          .subscribe((data: ErrorResponse) => {
            this.subcategoryErrors = data.subcategory_errors;
            this.validationErrors = data.validation_errors;
        });
    }
    

    You can use the *ngFor directive to iterate through an array and display html. Use ng-container to encompass multiple html elements without adding an extra div.

    <h1>Subcategory Errors></h1>
    <ng-container *ngFor="let errorList of subcategoryErrors">
      <h2>{{ errorList.sheet }}</h2>
      <p *ngFor="let error of errorList.errors">{{ error }}</p>
    </ng-container>
    
    <h1>Validation Errors></h1>
    <ng-container *ngFor="let errorList of validationErrors">
      <h2>{{ errorList.sheet }}</h2>
      <p *ngFor="let error of errorList.errors">{{ error }}</p>
    </ng-container>