Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Field Arrays' delete on index removes also later elements #114

Open
Alphenus opened this issue Mar 15, 2022 · 10 comments
Open

Field Arrays' delete on index removes also later elements #114

Alphenus opened this issue Mar 15, 2022 · 10 comments
Labels
bug Something isn't working

Comments

@Alphenus
Copy link

Alphenus commented Mar 15, 2022

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 Alphenus added the bug Something isn't working label Mar 15, 2022
@pablo-abc
Copy link
Owner

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
Copy link
Owner

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.

@pierre-H
Copy link

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
Copy link

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.

@gl-aagostino
Copy link

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.

@ChrisOgden
Copy link

ChrisOgden commented Jun 30, 2023

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
Copy link

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

@mpicciolli
Copy link

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

@canastro
Copy link

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

@ChrisOgden
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants