2

I'm trying to implement a classical "Update Object" feature.

I have a table with all my products listed, each line has an edit button opening a modal where I want to show product property values.

The property we focus on here is 'personas' and its value is an array of objects, each selected from a dropdown.

The form I'd like to prefill

I managed to show the right number of objects (3 in that example), but the values just don't set and the default option is selected in each case.

I tried to use angular 'patchValue()' function without success on that property.

Here is what I have as Typescript :

public personas = new FormArray([], [], []);

constructor(private fb: FormBuilder, public productService: ProductService) {
  this.productForm = this.fb.group({
      personas: this.personas,
    });
}

public onEdit(product: Product): void {
    if (product.personas.length > 0) {
     this.personaService.personas$.pipe(takeUntil(this._destroyed$)).subscribe((personas: Persona[]) => {
        const array = product.personas.filter(p => personas.some(p2 => p.id === p2.id));
        this.personas = this.fb.array(array.map(persona => new FormControl({
          id: persona.id,
          persona: persona.persona,
        })));
      });
    }
}

And this is what's in my template :

<div class="form-group">
  <label for="personas">Personas</label>
  <div id="personas" formArrayName="personas">
    <div *ngFor="let persona of personas.controls; let i = index;" class="d-flex m-1">
      <select
        *ngIf="!(personaService.isFetchingPersonas$ |async) && (personaService.personas$ |async) as options"
         class="form-control">
        <option *ngFor="let option of options" [ngValue]="option">{{ option.persona }}</option>
      </select>
  </div>
</div>

Thank you for your help

!!! EDIT !!!

I realized that while I tried to achieve my aim, I broke the process of creating new Products, as Persona property was not set correctly anymore.

So the Stackblitz project is slightely different from the above snippets. Because I moved back my project state to when it was functionnal.

STACKBLITZ : https://angular-ivy-cnmqhx.stackblitz.io

3
  • 3
    Can you create a Stackblitz ? Commented Feb 28, 2021 at 15:02
  • I'd like to, but I'm in an hospital actually and my connection is really bad. Stackblitz keeps trying to compile. I'll try to explore the hospital to get a better signal soon. Commented Feb 28, 2021 at 17:09
  • Stackblitz : stackblitz.com/edit/angular-ivy-cnmqhx?file=src/app/… Please read above "edit" section first. Commented Mar 1, 2021 at 15:13

1 Answer 1

1

At the bottom of hello.component.html I added this little helper to see what is inside the form.

<pre>
{{ productForm.value | json }}
</pre>

then I changed ngOnInit to look like this:

  public ngOnInit(): void {
    this.product.personas.forEach((persona: Persona) => {
      const option = this.options.find(x => x.id === persona.id);
      if (option) {
        this.addField(option);
      }
    });
  }

The idea here is to lookup each "option" and put that option into formArray, instead of "persona".

also a bit simplified addField method

  public addField(persona = {}): void {
    (this.productForm.get("personas") as FormArray).push(
      new FormControl(persona)
    );
  }

Working Stackblitz

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.