valtio icon indicating copy to clipboard operation
valtio copied to clipboard

`Error: object property already defined` when using `derive` with dynamic keys in object

Open T-Damer opened this issue 2 years ago • 1 comments

Full trace:

Uncaught Error: object property already defined
    at utils.js:258:13
    at Array.forEach (<anonymous>)
    at derive (utils.js:256:15)
    at SealCredStore.tsx? [sm]:44:23

So I am trying to initialize a store with not that simple approach. I have an array of objects which will define store contents. Take a look (cropped some code):

type DeriveGet = <T extends object>(proxyObject: T) => T
type DeriveStoreType = {
  [x: string]: (get: DeriveGet) => Promise<string[]>
}

interface SealCredStoreType {
  [ledgerName: string]: Promise<Ledger>
}

interface ComputedSealCredStoreType {
  [namedDerivativeContract: string]: Promise<string[]>
}

const state = proxy<SealCredStoreType>(dataToStorage) // which is SealCredStoreType

// get(state) === SealCredStoreType

function constructDerive() {
  const contractNameToDerivatives: DeriveStoreType = {
    derivativeContracts: async (get) => {
      const ledgers = await Promise.all(Object.values(get(state)))
      const derivatives = []
      for (const ledger of ledgers) derivatives.push(...Object.values(ledger))
      return derivatives
    },
  }

  const ledgerNames = Object.keys(data)
  for (const ledgerName of ledgerNames)
    contractNameToDerivatives[ledgerName] = async (get) => {
      return Object.values(await get(state)[ledgerName])
    }

  return contractNameToDerivatives
}

const SealCredStore = derive<SealCredStoreType, ComputedSealCredStoreType>(
  constructDerive(),
  { proxy: state }
)

Basically, I have a {[key]: value} in my store and I want to construct this object from another object (some sort of input, which you define only once from the start). So keys are dynamic, values are same objects

P.S.: I need Promise to use Suspense

T-Damer avatar Aug 10 '22 18:08 T-Damer

Hmm, I'm not quite sure how it causes an error. Does it only happen with async/await? Would you dig more into it? For example, try to create minimal reproduction with codesandbox.

dai-shi avatar Aug 11 '22 12:08 dai-shi

Closing as stale. Please open a new discussion with a reproduction.

dai-shi avatar Jul 10 '23 14:07 dai-shi