skip to Main Content

I have a context/store with a two objects (settings and defaultSettings) that are populated while fetching the data from the Database with createResource and I am adding ‘disabled’ property to the 2 first persons.

I need to compare settings and defaultSettings in every step of the code so I can activate or deactivate a button. But then the problem I have is, that if I am updating a property in settings later, it is also updated in defaultSettings.
Could you help me to fix that problem?

Here a part of the code with an example of data:

const data = { settings: 
     { persons: [
             { name: "a", firstName: "b"}, 
             { name: "c", firstName: "d"},
             { name: "e", firstName: "f"}, 
             { name: "g", firstName: "h"}
       ], 
       address: { zipCode: 12345, number: 342 }
     }}
        const disabledPerson = (settings) => {
        settings.persons.map((person, index) => {
                let entry = (index ==0 || index==1) ? ({...person, disabled: false}): ({...person, disabled: true})
                entriesafter.push(entr)
        
        setState("settings", "person", entriesafter)
        setState("defaultSettings", "person", entriesafter)
                
              })
        const getDefaultSettings = async () => {
            const settings = {
              method: "GET",
            }
            try {
              const response = await fetch('http://localhost:8083/getSettings', settings);
              const data = await response.json();
              setState("defaultSettings", state.defaultSettings = data[0].settings)
              setState("settings", state.settings = data[0].settings)
              disabledPerson(data[0].settings)
              
              return data[0].settings
            } catch (e) {
                console.log(e)
            }
          }
      const [defaultSettings] = createResource<settings[]>(getDefaultSettings)
        return (
        <><TextField value= {state.settings.address.zipCode}
        onChange={(e)=> {setState("settings", "address", e.currentTarget.value)/>
        </>
        )

2

Answers


  1. It is hard to say anything without seeing the actual code or a working demo, but if I understand you correctly you have two related signals and updating one overwrites the other one because signals are updated consecutively.

    If that is the case, you need to batch update both signals at the same time, so that values do not get overwritten: https://www.solidjs.com/docs/latest#batch

    batch(() => {
      setA(valueA);
      setB(valueB);
    });
    

    However, if you are using stores, stores are batched by default. You should not have such problems.

    Login or Signup to reply.
  2. It is a bit hard to diagnose the exact issue, but below I’ve included an example code snippet that might help you address the issue you’re facing and give you an idea of how to manage the state.

    const data = {
      settings: {
        persons: [
          { name: 'a', firstName: 'b' },
          { name: 'c', firstName: 'd' },
          { name: 'e', firstName: 'f' },
          { name: 'g', firstName: 'h' },
        ],
        address: { zipCode: 12345, number: 342 },
      },
    };
    
    const getDefaultSettings = async () => {
      try {
        // TODO: Fetch settings from API
        return data.settings;
      } catch (e) {
        console.log(e);
      }
    };
    
    const disabledPerson = (settings) => {
      const modifiedPersons = settings.persons.map((person, index) => {
        const disabled = index == 0 || index == 1;
        return { ...person, disabled };
      });
    
      return {
        ...settings,
        persons: modifiedPersons,
      };
    };
    
    const Settings: Component = () => {
      const { state, setState } = useContext(SettingsContext);
      const [defaultSettings] = createResource(getDefaultSettings);
    
      createEffect(() => {
        const settings = defaultSettings();
        if (!settings) return;
    
        const modifiedSettings = disabledPerson(settings);
    
        // Just for the sake of demonstration,
        // update 'settings' with the modified version
        // and update 'defaultSettings' with the non-modified version
        setState('settings', modifiedSettings);
        setState('defaultSettings', settings);
      });
    
      return (
        <>
          <div>Settings:</div>
          <For each={state.settings?.persons}>
            {(person) => (
              <div>
                {person.name} {person.disabled ? 'Disabled' : 'Enabled'}
              </div>
            )}
          </For>
          <div>Default settings:</div>
          <For each={state.defaultSettings?.persons}>
            {(person) => (
              <div>
                {person.name} {person.disabled ? 'Disabled' : 'Enabled'}
              </div>
            )}
          </For>
          <TextField
            value={state.settings.address?.zipCode ?? '0'}
            onChange={(e) =>
              setState('settings', 'address', 'zipCode', e.currentTarget.value)
            }
          />
        </>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search