How to retrieve errors from the backend when uploading an array using Angular?

I am facing an issue with my Angular application where I need to handle server-side failures when sending a list of strings to a backend server. Despite following tutorials, I am struggling to display error messages on the client side in case something goes wrong.

The angular component.ts file includes an upload method:

constructor(
    private readonly SVC: UploadService) { }

uploadStringlist(): void {
    let sarray: string[] = [];

    sarray.push("string1");
    sarray.push("string2");

    this.SVC.uploadList(sarray).subscribe(
     _ => { this.finished,emit(`protocols sent: next`)},
     err => { this.finished.emit(`Protocols sent: error` + err)},
     () => { this.finished.emit(`Protocols sent`)});
}

and the upload.service.ts file has the following method:

uploadList(slist: string[]): Observable<string> {
  return this.http.post<string>(apiurl, slist, httpOptions)
    .pipe(
      tap(res => log("uploaded protocol list to server", res)),
      catchError(handleError<string>("test")));
}

On the server side, there is an uploadController:

[HttpPost]
public IActionResult Post(string[] slist)
{
    foreach (var s in slist)
    {
       // do something
    }

    return StatusCode(409);
    //return Ok();
}

Regardless of what is returned from the controller, the result received on the client side is always "protocols sent." Ideally, I would like to receive a list of results for each entry in the string array or at least an error message if one occurs on the server side. However, I am unsure how to implement this.

Answer №1

Utilizing the ModelState in your controllers can establish a consistent error-handling pattern, ensuring that all error responses follow the same format.

When you use the BadRequest method along with ModelState, any errors will be captured and stored in the err variable as shown in this code snippet:

err => { this.finished.emit('Protocols sent: error' + err)},

This example demonstrates how to implement this in your own code.

[HttpPost]
public IActionResult Post(string[] slist)
{
    try
    {
        foreach (var s in slist)
        {
           // do something
           if(NotValid(s))
           {
               ModelState.AddModelError("", "Your message to the client");
           }
        }

        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        return Ok(new { successMessage = "success"});
    }
    catch(Exception ex)
    {
        // log your exception
        ModelState.AddModelError("", "Your generic error message");
        ModelState.AddModelError("SomeProperty", "Your error message about 'SomeProperty'");
        return BadRequest(ModelState);
    }
}

In your client-side code, make sure to update this line:

catchError(handleError<string>("test")));

To something like this:

catchError(error => handleError<any>(error)));

For more information on ModelState, refer to the documentation:
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-3.1

Answer №2

To identify the error, one approach is to raise an exception, like this:

throw new InvalidParameterException("An unexpected error occurred.");

Additionally, for Web API projects, ensure that error reporting is enabled (but disable it before going into production) in the web.config file:

<system.web>
    <customErrors mode="On" />
</system.web>

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

Tips for adding style to a child component from a parent component with multiple child components

I am faced with a situation where I have a child component in the form of a spinner that I need to display in two different places, each with its own unique style. In order to achieve this, I have attempted the following approach: my-loading-overlay ::ng-d ...

Utilize C# library to implement filters on Dimensions or Metrics within Google Analytics API

After successfully authenticating my app on Google Analytics and retrieving data on unique page views, I now want to obtain page views based on Traffic source. However, I am struggling with setting filters on the dimensions in my C# code. While I have ma ...

What is the reason WebPack is missing from the Visual Studio 2017 Dot Net Core 2.1 & Angular template?

Webpack 4 has introduced numerous enhancements, such as increased speed of up to 98% with minimal configuration. Interestingly, while Visual Studio 2017 with dot net core + angular 4 included webpack in the template, a recent project created in VS 2017 w ...

Is the relevance of Angular 1.x still prevalent in today's development landscape

Considering I have several projects in angular 1.x, I'm contemplating whether it's truly essential and efficient to upgrade them to angular 4 or a later version. The smaller dashboards do not necessarily require an update since they are only use ...

The reason for duplicating the import of an NPM package in TypeScript (specifically for Firebase Functions)

I recently found this code snippet in the Firebase documentation: import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; import 'firebase-functions'; admin.initializeApp(); I'm curious ...

What is preventing storybook from working with checkboxes?

My checkbox component is not recognizing the types specified within it. Below is the component I am trying to test: interface IProps { name?: string; className?: string; style?: React.CSSProperties; label?: string; color?: 'primary' | ...

Identifying system reboot on Windows 8 - Failure to trigger SessionEnding event

My WPF application has the ability to detect when a user shuts down Windows 8 from the Settings charm through the SessionEnding event. If the user selects Shut down, I receive the message "Session Ending Due To SystemShutdown" SystemEvents.SessionEnding ...

Encountering Issues with Requesting Multiple Permissions in MAUI (Previously Successful with Xamarin.Essentials)

Transitioning from Xamarin.Essentials to MAUI has posed some challenges, particularly with the RequestAsync calls failing to return from the await in order to continue executing the rest of the function. Currently, the app needs to be launched 4 times befo ...

Angular UI failing to refresh despite Observable subscription activation

I'm facing an issue with my Angular page where the UI is not updating when the observable parameter from a service changes. I've experimented with storing the observable result in a flat value and toggling a boolean to update the UI, but none of ...

Select2 is throwing an error that says "Unidentified problem with property 'results'."

Currently, I am working on populating a searchable Select2 form-control with search results extracted from Active Directory. Let's take a look at the select2 function implementation: $("#networkUserSelect").select2({ ajax: { url: ' ...

What are the distinctions between using findById({_id:historyId}) and findById(historyId) in Mongoose?

While working on one of my projects, I encountered a situation that left me a bit confused. I am trying to understand if both approaches outlined below will yield the same output, and if so, why? async getHistory( historyId: string) { const { h ...

Continuously converting methods recursively until the array is fully processed

My current code has a method that is not very efficient and does not scale well. The object y is an array consisting of key/value pairs, each containing two properties: 1. A unique string property called name. This value is identified by the childre ...

Organizing Information in SQL

I've been trying to understand SQL hierarchy tutorials, but I couldn't find one that fits my application. I'm developing a C# ASP.NET app and I want to create a tree view hierarchy from SQL data. This is how the hierarchy should function: ...

Updating token (JWT) using interceptor in Angular 6

At first, I had a function that checked for the existence of a token and if it wasn't present, redirected the user to the login page. Now, I need to incorporate the logic of token refreshing when it expires using a refresh token. However, I'm enc ...

Creating distinct applications on IIS for an Angular client and a .Net Core WEB API

When deploying angular 2+ applications with .net core Web APIs on IIS, what practice is considered the best? Combining both the Angular Client and the .Net Core Web API into a single application or Creating separate applications for the Angular Client an ...

The deployment of the Angular application to Azure using Github Actions was unsuccessful due to the lack of a package.json file

When attempting to deploy an Angular(10) WebApp to Azure using Github Actions for CI/CD, I encountered an error indicating that the package.json file could not be found during the execution of the npm install command. Below is my yml file: name: Deploy to ...

Searching for variables within files using Node.js and constructing an object from the results

Trying to figure out how to streamline this process. Here's the directory structure I'm working with: src/ modules/ clients/ i18n/ en-US.ts tasks/ i18n/ en-US.ts So, ea ...

Error message: Unable to set the uploaded file in the specified state within a React application

I am currently working on a react application that involves file uploads. My goal is to update the state variable with the uploaded file in either .docx or .pdf format as soon as it is uploaded. However, when I try to set the state, it shows up as undefine ...

Displaying JSON data in a TextBox using C#

As a beginner in C#, I have a question regarding my program. It involves sending an API request to a server and displaying the data received in JSON format on a TextBox. public void button2_Click(object sender, EventArgs e) { var OTPSCODE = ...

The filter element is no longer supported by react-native-svg, causing SVGR to remove certain elements

I'm having trouble using my svg file in react native. I attempted to convert the svg to react native but received a warning: "/* SVGR has dropped some elements not supported by react-native-svg: filter */". The result is not exactly what I w ...