1
votes

I'm working with .Net Core 3.0 and Angular 8. I'm building a form using Angular's Reactive Forms and FormBuilder, with FormGroup and FormArray. Basically, I have two models which look like this in the .Net API:

public class Parent
{
    [Required]
    public string Name { get; set; }

    [Required]
    public List<Child> Children { get; set; }
}

public class Child
{
    [Required]
    public string Name { get; set; }

    [Required]
    public string Description { get; set; }
}

In Angular I'm using FormBuilder to build a form like this:

// In the component class
// this.fb is type FormBuilder
form = this.fb.group({
    name: [''],
    children: this.fb.array([])
});

// Later on, I build the form.children like this
for (var x = 0; x < 9; x++) {
    this.form.get('children')
        .push(this.fb.group({
            name: [''],
            description: ['']
        });
}

Note the [Required] attribute on the models in .Net. So if I submit my form without values for the required properties, .Net returns a response which looks like this:

"errors": {
    "name": ["The Name field is required"],
    "children[0].name": ["The Name field is required"],
    "children[0].description": ["The Description field is required"],
    // and so on
}

I can obviously tell my Angular form that the name field has an error, because if I loop through the errors in that response I can say this.form.get('key') where key is each key in the errors object. However, that does not seem to work for the children FormArray.

So far the only way I've been able to get it to work is by manually parsing the error keys. That feels very wrong though, because I'm having to manually parse the index values from each of the children[index].fieldName errors.

I'm aware of client side validation using built-in and customer validators in Angular. Those will also be in place, but I'd like to be able to utilize the API's 400 response in the event that something gets past the client validation.

Am I missing something? Is there a way to take the .Net HTTP 400 error response - specifically the errors object - and add those errors to the correct FormGroup within the children FormArray (e.g. children[0].name)? I suppose it's possible I'm using FormGroup and FormArray incorrectly due to lack of familiarity with Reactive Forms (this is my first time with them). But from the things I read, this felt correct to me.

1

1 Answers

1
votes

Let's breakdown a couple of your questions and statements:

Is there a way to map the .Net HTTP 400 error response directly to the Angular FormGroup

No, you cannot "map" an HTTP 400 response to an Angular component of any kind, I am not sure what you mean by this in a way. An HTTP status code should be checked by an if statement or perhaps a catch block is entered using some HTTP libraries that will throw for certain HTTP status codes.

But from the things I read, this felt correct to me

I don't think you are on the right track with your code. It would be best to start by not doing PostBacks to handle error validation with Angular Reactive Forms or any web form validation for that matter. You should have client side validation that handles validating and ensures valid data posted to your APIs. Of course, you will still fire your server side model validation as well to verify that data is valid, you always do this with any post to an API, you run server side validation as you never know what client is calling your APIs nor do you care if the Request is valid.

You should be using Reactive Form Validators

*Do not get hung up on repeating validation code Client Side. ASP.NET Data Annotation immediately leads to this desire and thus ASP.NET MVC Unobstrusive Validation exists for Razor views. I have gone far done this path. NodeJs is a great solution because the Javascript for validation can be shared client side and server side. There is an expensive architecture called ServiceStack that uses Fluent Validation that has some ability to share server side validation client side but, in the case of Angular Reactive Forms, you still have separate code client side when using Angular Reactive Forms because really your Validators are the proper way to tell Angular Reactive Forms if a field is invalid. For .NET Core and Angular Reactive Forms, it is efficient and perhaps best just to have separate validation mechanisms for client side and server side *