splitAtom - Inside a writable atom after fetching data from server, how to create atoms dynamically from an array data using splitAtom?

143 views Asked by At

I am trying to create atoms from an array using split atom, but I get typescript and TypeError: todoAtoms.map is not a function.

Below is the code that I used :

In file appStateAtom.ts, I have a declared atoms

// In response from server I get the below todo object. Here, I am using it directly(mocked) for simplicity
export const todo = [
    {
        task: 'help the town',
        done: false,
    },
    {
        task: 'feed the dragon',
        done: false,
    },
]

export const todoStateAtom = atom([] as typeof todo)
export const todoAtomsAtom = atom([])

In file appDispatcher.ts, I set this atom

 const fetchTodoAtom = atom(null, async (_get, set) => {
     try {
         const fetchTodoRes = await fetchTodo() // here I make api call

        // items are first populated from a server request
         set(
             todoStateAtom,
             fetchTodoRes.data
         )
      } catch (error) {
          console.log(error)
     }
  )


 const setupTodoAtom = atom(
        (get) => get(todoTableDataAtom),
        async (_get, set) => {
            try {
                await set(fetchTodoAtom)
                set(todoAtomsAtom, splitAtom(todoStateAtom))  // I get typescript error here
            } catch (error) {
                console.log(error)
            }
        },
    )

Then I want to use todoAtomsAtom in my component

import React, { useCallback, useEffect, useState } from 'react'

import { dispatcherStateAtom } from '@/jotai_model'
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
import { todoAtomsAtom } from '@/jotai_model/atoms/todoState'
import { Todo } from '@/modules/todo/Todo'

export const TodoContainer = () => {
    const { setupTodoAtom } = useAtomValue(dispatcherStateAtom)
    const setupTodo = useSetAtom(setupTodoAtom)

    const [todoAtoms, dispatch] = useAtom(todoAtomsAtom)

    useEffect(() => {
        async function fetchSetupData() {
            await setupTodo()
        }
        fetchSetupData()
    }, [])

    return (
        <div>
            {todoAtoms.map((todoAtom, idx) => (
                <Todo
                    key={idx}
                    todoAtom={todoAtom}
                />
            ))}
        </div>
    )
}

Where I do set(todoAtomsAtom, splitAtom(todoStateAtom)), I get error

Argument of type 'WritableAtom<PrimitiveAtom<{ task: string; done: boolean; }>[], [SplitAtomAction<{ task: string; done: boolean; }>], void>' is not assignable to parameter of type 'SetStateAction<never[]>'.
  Type 'WritableAtom<PrimitiveAtom<{ task: string; done: boolean; }>[], [SplitAtomAction<{ task: string; done: boolean; }>], void>' is missing the following properties from type 'never[]': length, pop, push, concat, and 29 more.ts(2345)

And Inside my component I get error

TypeError: todoAtoms.map is not a function

Where am I going wrong?

0

There are 0 answers