How to achieve that in the property of a model that expects an array the added value is kept within the array?

38 Views Asked by At

I have the following models. as you can see email expects a string array

export interface Member {
  id: string;
  name: string;
  lastName: string;
  emails: string[];
}

export type MemberPreview = Omit<Member, "id">;

In addition I have defined the following configuration of a form using formly

form = new FormGroup({});
model: MemberPreview = {
  name: "",
  lastName: "",
  emails: [],
};
fields: FormlyFieldConfig[] = [
  {
    key: "name",
    type: "input",
    props: {
      label: "Name",
      required: true,
    },
  },
  {
    key: "lastName",
    type: "input",
    props: {
      label: "Lastname",
      required: true,
    },
  },
  {
    key: "emails",
    type: "input",
    props: {
      label: "Emails",
      required: true,
    },
  },
];
options: FormlyFormOptions = {};

Template:

<pre>{{ model | json }}</pre>
<hr />
<pre>{{ form.value | json }}</pre>

<form [formGroup]="form" (ngSubmit)="onSubmit()" autocomplete="off">
    <formly-form
        [form]="form"
        [fields]="fields"
        [model]="model"
        [options]="options"
    ></formly-form>
    <button type="submit">Submit</button>
</form>

Model initial state

{
  "name": "",
  "lastName": "",
  "emails": []
}

Model after adding values

{
  "name": "john",
  "lastName": "doe",
  "emails": "[email protected]"
}

What I try is that when adding a value in email, that value is inside the array.

Expected result

{
  "name": "john",
  "lastName": "doe",
  "emails": ["[email protected]"]
}

How can I achieve this result? Thanks in advance

update 0

I thought that using hooks could approximate the expected result. I attach an example

{
  key: "emails",
  type: "input",
  props: {
    label: "Emails",
    required: true,
  },
  hooks: {
    onInit: (field: FormlyFieldConfig) => {
      field.form?.get("emails")?.setValue(["abc"]);
    },
    onChanges: (field: FormlyFieldConfig) => {
      field.form?.get("emails")?.setValue("[xml]");
    },
  },
},
1

There are 1 best solutions below

0
Mario On

I managed to get the expected result using formly hooks as follows

{
  key: "emails",
  type: "input",
  props: {
    label: "Emails",
    required: true,
  },
  validators: {
    validation: [emailValidator],
  },
  hooks: {
    onInit: (field: FormlyFieldConfig) => {
      field.form?.get("emails")?.valueChanges.subscribe({
        next: (value) => {
          this.model.emails = [value];
        },
      });
    },
  },
},

I have confirmed that the validations works

I don't know if this is a proper solution. In any case, I am attaching a complete example in case it is relevant.

form = new FormGroup({});
model: MemberPreview = {
  name: "",
  lastName: "",
  emails: [],
};
fields: FormlyFieldConfig[] = [
  {
    key: "name",
    type: "input",
    props: {
      label: "Name",
      required: true,
    },
  },
  {
    key: "lastName",
    type: "input",
    props: {
      label: "Lastname",
      required: true,
    },
  },
  {
    key: "emails",
    type: "input",
    props: {
      label: "Emails",
      required: true,
    },
    validators: {
      validation: [emailValidator],
    },
    hooks: {
      onInit: (field: FormlyFieldConfig) => {
        field.form?.get("emails")?.valueChanges.subscribe({
          next: (value) => {
            this.model.emails = [value];
          },
        });
      },
    },
  },
];
options: FormlyFormOptions = {};