felte icon indicating copy to clipboard operation
felte copied to clipboard

Field Arrays' delete on index removes also later elements

Open Alphenus opened this issue 3 years ago • 10 comments

Describe the bug When attempting to remove a field from a field array at index i using unsetField('fieldArray${index}'), all members of that array from i to end get removed.

I tried to use alternative ways to remove single entries (e.g. slicing and combining arrays), but same issue re-occurs. However, when replicating similar form without felte using a local variable as 'store', it works as expected.

To Reproduce Steps to reproduce the behavior:

  1. Grab code from https://felte.dev/docs/svelte/field-arrays
  2. Create multiple new interest items
  3. Attempt to remove some of the first items
  4. All items after that get removed

Expected behavior Only the selected item should disappear.

Screenshots By reactively logging interests -variable ($: console.log(interests)), it is shown that elemets are removed one-by-one from the array after calling remove function: image

Environment (please complete the following information):

Other stuff I'm quite new with svelte, so this can be user error of sort.

Alphenus avatar Mar 15 '22 09:03 Alphenus

Thanks for the report! This seems to be an issue on my side. But it works if you remove the (interest.key) part.

<script>
  import { createForm } from 'felte';

  const { form, data, addField, unsetField } = createForm({
    initialValues: {
      interests: [{ value: '' }],
    },
  });

  $: interests = $data.interests;

  function removeInterest(index) {
    return () => unsetField(`interests.${index}`);
  }

  function addInterest(index) {
    return () => addField(`interests`, { value: '' }, index);
  }
</script>

<form use:form>
  {#each interests as interest, index}
    <div>
      <input name="interests.{index}.value" />
      <button type="button" on:click="{addInterest(index + 1)}">
        Add Interest
      </button>
      <button type="button" on:click="{removeInterest(index)}">
        Remove Interest
      </button>
    </div>
  {/each}
</form>

I'll update the documentation for now but will leave this open to check why adding a key breaks this.

pablo-abc avatar Mar 15 '22 11:03 pablo-abc

As a further update. I'm not sure how I did not catch this before but: If you want to key your items (using interest.key like the example), add the attribute data-felte-keep-on-remove to the<input> element.

I'm not quite sure how this did not cause any conflicts before. But that'd be the recommendation for now. Key your items + add the attribute to any input within your each.

pablo-abc avatar Mar 17 '22 13:03 pablo-abc

Did someone find another solution ? I tried to use key + data-felte-keep-on-remove in a fieldset inside the loop but I have the same problem as @Alphenus . @pablo-abc

pierre-H avatar Jan 19 '23 18:01 pierre-H

What I mean is that : I use key and data-felte-keep-on-remove and I try to set the data programmatically.

Only one line is setted if I use $data = ... or setData. Here is the result with a $: console.log($data.items); : image

If I use setInitialValues with reset I've got an error because step by step the items becomes undefined.

pierre-H avatar Jan 19 '23 19:01 pierre-H

I have a similar problem where upon removing a field via unsetField a completely different array field loses all of its data. I've tried about 100 different ways to work around it, but it seems to be hellbent on wiping the data from another array. This happens to be an array of selects. I wonder if that has anything to do with it.

gl-aagostino avatar Apr 13 '23 21:04 gl-aagostino

I have a similar problem where upon removing a field via unsetField a completely different array field loses all of its data. I've tried about 100 different ways to work around it, but it seems to be hellbent on wiping the data from another array. This happens to be an array of selects. I wonder if that has anything to do with it.

I am seeing this as well, it isn't always consistent either. In my case I have an array of items which have sub-values. For example in my testing just now I had

Before Delete

"step1": { 
   "item_fczxfm0p": { 
      "fldOvLgT8NrE7ZEOT": "1", 
      "fldcVoNTkahMLtrJR": "", 
      "fldp3O05kE14AC0Kn": "" 
   }, 
   "item_0y8l9ofczxfm": { 
      "fldOvLgT8NrE7ZEOT": "2", 
      "fldcVoNTkahMLtrJR": "", 
      "fldp3O05kE14AC0Kn": "" 
   }, 
   "item_gmjsl7keutr": { 
      "fldOvLgT8NrE7ZEOT": "3",
      "fldcVoNTkahMLtrJR": "", 
      "fldp3O05kE14AC0Kn": ""  
   } 
 }

After

"step1": { 
   "item_0y8l9ofczxfm": { 
      "fldOvLgT8NrE7ZEOT": "2", 
      "fldcVoNTkahMLtrJR": "", 
      "fldp3O05kE14AC0Kn": "" 
    }, 
   "item_gmjsl7keutr": { 
      "fldOvLgT8NrE7ZEOT": "3" 
    } 
 }

I only deleted the first item but fields in the third item disappeared

ChrisOgden avatar Jun 30 '23 14:06 ChrisOgden

On continued investigation I found the following. I am dynamically generating the HTML elements, so clicking add item adds a new object to the step1 array of HTML elements to be generated.

The problem goes away when I use delete to remove the object from HTML array vs using array.splice, this creates a new problem though because I now have an object with bogus lengths since there are empty elements.

At this point I think I am going to have to work around this scenario since the reactivity with felte appears broken for this use case

ChrisOgden avatar Jul 07 '23 21:07 ChrisOgden

I had the same problem #230 but I didn't find a solution. Any news @ChrisOgden ?

mpicciolli avatar Oct 28 '23 23:10 mpicciolli

Yeah this issue is a bit inconvenient as it prevents you from using animate:flip

canastro avatar Jan 18 '24 12:01 canastro

I had the same problem #230 but I didn't find a solution. Any news @ChrisOgden ?

I did something along the lines of this:

const isDirty = steps[stepIndex][rIndex].dirty
if (isDirty) {
	unsetField(`${sKey}.${rKey}`)
}
delete steps[stepIndex][rIndex]
const cleanSteps = _.filter(steps[stepIndex])

It is a little out of context and seems messy but it appears to have worked around it. I know I played with it a lot to get to this point. The challenge with mine is the elements are being dynamically rendered based on an object separate from the form values object.

ChrisOgden avatar Jan 22 '24 15:01 ChrisOgden