Sapper/Svelte update state inside a component after another component is done posting

469 views Asked by At

I'm aware of this q&a but still not able to apply it in my situation.

I'm using sapper and have two components. Component2 is to create options or category for a menu. Component1 display the menu with all the options/categories created. Also, component1 includes the component2 in its body.

My issue is when I use component1 and hit save, everything is working(inputs data saved to db) now component1 needs to reflect the new option/category that was just created but it is not aware of the changes. How do I make my component1 (which display all the categories) aware of the changes/update/newcategory once I click save in component2?

Component2 code: createcategoy.js is working fine and post the data to my db so it is not an issue.

<script>
...code to get locationid unrelated to my issue

function createcategory(event){
  let categoryorder = event.target.categoryorder.value
  let categoryname = event.target.categoryname.value
  let categorydescription= 
   event.target.categorydescription.value

 
  fetch('createCategory', {
  method: 'POST',
  credentials : 'include',
  headers: {
  'Accept': 'application/json',
  'Content-type' : 'application/json'
  },
  body: JSON.stringify({
  
  location_id : locationid,
  category_order : categoryorder,
  category_name : categoryname,
  category_description :categorydescription
  })
  }).then(response => response.json())
  .then(responseJson => {
  console.log("All Is Well. Category created 
      successfully")
  })
  .catch(error => console.log(error));

  
  }

</script>
html form...

Now here is component1 which display locations and each location has its own categories created by component2:

  <script>     
     import { onMount } from 'svelte';
     import { goto } from '@sapper/app';
     import Createcategory from './createCategory.svelte'

     let locations = []
     onMount(async () => {

     fetch('menubuilder', {
     method: 'POST',
     credentials : 'include',
     headers: {
     'Accept': 'application/json',
     'Content-type' : 'application/json'
     },
     body: JSON.stringify({

     })
     }).then(response => response.json())
     .then(responseJson => {
     locations = responseJson.info
     })
     .catch(error => console.log(error));

     }) //onMount fn
   
   </script>  

    <h1> Menu Builder </h1>
         
    <dl>
    
      {#each locations as location}

  
       
        <br>
    <h1>{location.locationname} </h1>
        <p>{location._id} </p>
          

   <!-- This is component2 where I use to create new 
      category-->
  <Createcategory locationname= 
  {location.locationname} locationid={location._id}/>
  </dt>
  
  
  <dd> 
            
     {#each location.locationcategories as item}
     <div >       
       <p>{item.categoryname} </p>: 
       {item.categorydescription}
       
     </div>
     {/each}
      
        
  
  {/each}

</dl>

Now, my only struggle is with how sapper/svelte state works. How do I make component1 update it is state/dom when I submit the component2 that creates the category.

I read the reactivity section in the documentation, the locations variable is assigned inside component1 but component2 is the one responsible for creating the new category.

So, what should I do to update component1 (locations variable and its dom) when component2 save the category to db?

1

There are 1 answers

1
Stephane Vanraes On BEST ANSWER

There are two common ways to do this:

  1. raise an event after posting the new category, your new workflow will be something like:

Component2 pushes to the server
Component2 raises an event categoryAdded with as payload the category. Component1 reacts to this event by appending the given category to it's array.

Or, an in my opinion better approach:

  1. add your categories in a store that is outside both components.

Component1 will simply display the contents of the store.
Component2 will push new items to the store.

The store itself, will be responsible for getting/pushing the data from and to the server. This has the two extra benefits:

  • The components are only concerned with displaying categories and do not care where they come from or where they go.
  • You can easily change the way categories are stored, which endpoint it uses, ...