Code Junkie
Code Junkie

Reputation: 83

How do I patch values back to an object in Angular 13?

I have an issue with patchValue and setValue in Angular 13.

I have a form I created using formBuilder called manageUsers. In it, I have a key called userRoles that contains an array of booleans.

The manageUsers form contains checkboxes for the user roles. The array of booleans turns those checkboxes into checked/unchecked based on the boolean values.

When you first visit the page, the userRoles array in the manageUsers form, by default, look like this...

this.manageUsers.value.userRoles = [false, false, false, false, false]

When a user checks or unchecks a checkbox, the form recognizes a change in state and the "Save Changes" button enables. If someone clicks the "Save Changes" button, then the manageUsers form gets sent to an endpoint where it is saved in a database.

When you select a user, for example "Anthony", the information for that user checks against a list of 5 user roles that looks like this...

[
    {
        "id": 1,
        "name": "AnalyticalAdmin"
    },
    {
        "id": 2,
        "name": "Analyst"
    },
    {
        "id": 4,
        "name": "AdminReviewer"
    },
    {
        "id": 5,
        "name": "SystemAdministrator"
    },
    {
        "id": 6,
        "name": "CaseworkSTRTechLeader"
    }
]

to see what roles are assigned to Anthony. Let's say "AdminReviewer" is assigned. Then the resulting userRoles array would look like this...

this.manageUsers.value.userRoles = [false, false, true, false, false]

That means the third checkbox ("AdminReviewer") would be appear checked in the form and the others would not be checked. So let's say then you were to check the second checkbox ("Analyst"). The updated userRoles in the manageUsers form would look like this...

this.manageUsers.value.userRoles = [false, true, true, false, false]

What I've done is written code to compare that array with the list of 5 roles above.

The resulting array looks like this...

[
    {
        "id": 2,
        "name": "Analyst"
    },
    {
        "id": 4,
        "name": "AdminReviewer"
    }
]

So far so good.

Here's my problem...

When I go to patch that array of objects BACK INTO the manageUsers form, the result looks like this...

[
    {
        "id": 2,
        "name": "Analyst"
    },
    {
        "id": 4,
        "name": "AdminReviewer"
    },
    true,
    false,
    false
]

Angular, for some reason, wants to add booleans to make up for the three missing elements. But here's the thing, I ONLY WANT the this.manageUsers.value.userRoles form object to contain the two objects. I don't need the superfluous booleans.

I just want the this.manageUsers.value.userRoles object (that I'm sending back to the database) to look like this...

[
    {
        "id": 2,
        "name": "Analyst"
    },
    {
        "id": 4,
        "name": "AdminReviewer"
    }
]

NOT LIKE THIS...

[
    {
        "id": 2,
        "name": "Analyst"
    },
    {
        "id": 4,
        "name": "AdminReviewer"
    },
    true,
    false,
    false
]

I've tried using BOTH .patchValue and .setValue methods, but they don't work.

How do I patch an array of objects and tell Angular to NOT include booleans for the roles I didn't want to account for?

*UPDATED...

Here is the code I use set the userRoles array...

this.manageUsers = this.formBuilder.group({
      id: null,
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      userInitial: ['', Validators.required],
      netUserName: ['', Validators.required],
      workPhone: [null, [Validators.required, Validators.pattern("[0-9 ]{10}")]],
      email: ['', Validators.required],
      userTitle: ['', Validators.required],
      userRoles: new FormArray([], Validators.required),
      incidents: new FormArray([], Validators.required)
    })

Then, I created a property called userRolesArray...

public get userRolesArray() {
    return this.manageUsers.controls.userRoles as FormArray;
  }

Then, I created a property called addCheckboxesToManageUsers() and call that in the ngInit() method.

private addCheckboxesToManageUsers(): void {
    this.listOfUserRoles.forEach(() => this.userRolesArray.push(new FormControl(false)));
  }

Upvotes: 0

Views: 1091

Answers (1)

Mohit Sharma
Mohit Sharma

Reputation: 648

after getting value from this.manageUsers.value.userRoles use reducer to remove all boolean type of value.

const data = [
    {
        "id": 2,
        "name": "Analyst"
    },
    {
        "id": 4,
        "name": "AdminReviewer"
    },
    true,
    false,
    false
]

const newArr = data.reduce((prev, curr) => {
  if (typeof curr !== 'boolean') prev.push(curr);
  return prev;
}, []);

console.log(newArr)

updated one-liner

data.filter(data => typeof data != 'boolean')

Upvotes: 1

Related Questions