#I have no clue what I am doing wrong

24 messages · Page 1 of 1 (latest)

shadow mason
#

Hello, I am very new to Solid, I am working with stores right now to represent this data structure:

const question = {
  title: String,
  id: number,
  sub_questions: question[]
}

I am using a store to store an array of these questions, and have an App component that renders them

function App() {
  const default_question = 
    { title: "question", id: 0,  sub_questions: []} 

  const [questions, setQuestions]=createStore([default_question]);  
  return <>
    <ol>
      <For each={questions} fallback={<div>No questions saved</div>}>
        
        {(question,i) => {
           return <li>
           <input 
            type="text" 
            value={question.title} 
            onInput={e => setQuestions(i(),"title",e.target.value)}
          />

          <For each={question.sub_questions} fallback=<p>no subquestions</p>> 
            {(sub_question, j) => {
            return (
                <input 
                  type="text" 
                  value={sub_question.title} 
                  onInput={e => setQuestions(i(), "sub_questions", j(), "title", e.target.value)}
                />
              )
            }}  
          </For>         
          <button onClick={_ => setQuestions(0,"sub_questions",q=>[...q,{title:"s",id:0,sub_questions:[]}])}>
            add sub question to question #{i()+1}
          </button>
          </li>
        }}
      </For>
    </ol>
    <button onClick={_ => setQuestions((questions) => [...questions, default_question])}>
      add question
    </button>
 </>
}

I have no idea why, but each update I add a sub_question via the onlclick setQuestions, it updates the whole store to have the same values for each question in the question array, I have not found a way around this/why it is happenings, pls help. I have tried using a fixed index 0 for the setQuestions function, but this way still updates ALL the questions in the array each time i add a sub question to the fist item in the array. pls help

cosmic oar
shadow mason
#

how do I do that, never used playground before

cosmic oar
#

take the code u have and make it produce the same problem in there

shadow mason
#

ok

cosmic oar
#

though one thing already stands out - you're reusing default_question

#

it's possible that since you're reusing it, adding a sub question is adding it to that single question instance which is used for all the elements of the array

#

instead prefer to have a makeDefaultQuestion function that returns a new object each time

shadow mason
#

will try

#

i did the playground thing btw, do you want me to send it as a link or smth

cosmic oar
#

yeah plz

shadow mason
cosmic oar
#

as a general rule if you can reproduce your issue in playground/stackblitz you'll be much more likely that someone will a) want to help and b) be able to fix your problem

shadow mason
#

thanks for the advice

cosmic oar
#

also you're using 0 instead of i()

shadow mason
#

Yeah, anyways the issue got fixed by just making default_question a function, but I have no clue why that was causing a problem, can you explain it to me please?

cosmic oar
#

when you create default_question as a single object, that same object is reused for all the entries of that array, so even though you may have 5 questions, they all actually point to the same object and so updating one updates all of them

#

using the function instead creates a new object instance each time, so each entry of the questions array is unique

shadow mason
#

damn so under the hood Javascript just points to one shared memory adress where default_question is read instead of cloning it into seperate memory locations, that kinda sucks. well everything makes sense now thanks for your help.

cosmic oar
#

yep, you have to explicitly clone the object using { ...default_question } (which is only a shallow clone) or do a deep clone or just construct a whole new object

#

btw you can make your life a bit easier and do this

#

instead of doing setQuestions(i(), "title", ...) you can get a setter for that specific question and call setQuestion("title", ...)

#

same goes for sub questions or any other objects in a store