0

please i have one question : in Main.svelte components i have array footerItems :

<script>
 let footerItems = [
 {
 'left' : [
   {
     'id' : 'item #1',
     'value' : true 
   },
   {
     'id' : 'item#2',
     'value' : true 
   } 
 ],
 'right' : [
   {
     'id' : 'item#3',
     'value' : true
   }
 ]
 }
]
</script>

in components Data.svelte i have :

<script>
import Main from './components/Main.svelte';
export let footerItems;
let addData = {
    'id': 'map', 
    'value': false
};
    footerItems['left'].push(addData);
</script>

I need to add a new object to the footerItems ['left'] from the Data.svelte component. can anyone advise me how to solve this?

2 Answers 2

2

I recommend that you use writable / subscribe ..etc to manage your store. Also methods like push / splice can break reactivity (if you use)

In Main.svelte

export const footer =writable([
    {
        'left' : [
        {
        'id' : 'item #1',
        'value' : true 
        },
        {
        'id' : 'item#2',
        'value' : true 
        } 
        ],
        'right' : [
        {
        'id' : 'item#3',
        'value' : true
        }
        ]
        }
])

In Data.svelte

import {footer} from './store.js'

let leftSideArr
let addData = {
    'id': 'map', 
    'value': false
};

 
  footer.subscribe(val=>{
      leftSideArr=val[0].left
      leftSideArr=[...leftSideArr,addData]
  })
Sign up to request clarification or add additional context in comments.

Comments

0

If Main.svelte and Data.svelte 'are connected' (Data 'sits' inside Main), you can simply pass in the array as a property with the bind: directive

[Main.svelte]
<script>
  let footerItemsParent
</script>

<Data bind:footerItemsChild={footerItemsParent} />

<!-- or simply <Data bind:footerItems /> -->
<!-- if name of variable is the same in both parent and child component -->
[Data.svelte]
<script>
  export let footerItemsChild;
</script>

With the bind: directive the variables are 'connected' and all modifications to the varible inside the component are changing the parent instance

If it's an array, it can be altered either by .push() followed by an assignment of the modified variable to itself important >> the assignment triggers the update where the variable is used

array.left.push(addData)
array = array

//OR

array = [...array, addData]

Even if the assignment to itself looks a bit weird - when modifiying a nested field like in this case the .push syntax might be better to read, since first setting the subfield on a variable an then assigning the variable breaks the reactivity again

let subArr = array[index].key
subArr = [...subArr, addData]    // not reactive

//OR

array[index].key.push(addData)
array = array                    // reactive


array[index].key = [...array[index].key, addData] // reactive, but harder to read

In case both Components have no direct connection, moving the footerItems to a store would be another solution.

[store.js]
import {writable} from 'svelte/store'

export const footerItemsStore = writable(
 ...
 data
 ...
)

Inside the component the store can (after being imported) easily referenced by prefixing the store name with $ ( = auto-subscription)

[Component.svelte]
<script>
  import {footerItemsStore} from './store.js'

  $footerItemsStore = [...$footerItemsStore, newItem]
</script>

NOTE Neither the imported property from the parent component nor the store value can be directly modified on the top level of the script tag in the component => If the modification should happen with mounting the component, the functionality can happen in the onMount function

Have a look at this REPL with both the parent-child-component situation and the store alternative

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.