title: Firestore doc field update in react app giving TypeError unless I refresh first
body: <p>I have a react app which allows creation of lists for logged in users (groceries, todo, etc) and stores data on firebase.firestore. It's still in development using localhost. If I create a new list, add items to it and immediately edit the item description, I get a TypeError and item description doesn't update in app or firestore. If I pick a different list to display, then click back to new list or refresh the browser before I edit the item description, everything works fine. It just doesn't work if I specifically create new list, add items to it, and immediately try to edit the item description, even though I check firestore before submitting change and the new list and new items are shown to exist.</p>
  <p>Any idea why the await checkDoc in the handleSubmit isn't working unless I refresh app in browser first?</p>
  <p>I included firestore screenshots before and after app refresh in case it matters. They seem identical to me.</p>
  <p>Github repo is branch edit-item
  <a href="https://github.com/PrinceCorwin/iList/tree/edit-item" rel="nofollow noreferrer">github repo</a></p>
  <p>error showing in console when I update item description without refreshing:</p>
  <pre><code>TypeError: u.indexOf is not a function
      at Function.e.ot (prebuilt-67479dbf-318e5a2c.js:878)
      at Bs (prebuilt-67479dbf-318e5a2c.js:14560)
      at e.doc (prebuilt-67479dbf-318e5a2c.js:18281)
      at handleSubmit (EditItem.js:32)
      at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
      at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
      at invokeGuardedCallback (react-dom.development.js:4056)
      at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4070)
      at executeDispatch (react-dom.development.js:8243)
      at processDispatchQueueItemsInOrder (react-dom.development.js:8275)
      at processDispatchQueue (react-dom.development.js:8288)
      at dispatchEventsForPlugins (react-dom.development.js:8299)
      at react-dom.development.js:8508
      at batchedEventUpdates$1 (react-dom.development.js:22396)
      at batchedEventUpdates (react-dom.development.js:3745)
      at dispatchEventForPluginEventSystem (react-dom.development.js:8507)
      at attemptToDispatchEvent (react-dom.development.js:6005)
      at dispatchEvent (react-dom.development.js:5924)
      at unstable_runWithPriority (scheduler.development.js:646)
      at runWithPriority$1 (react-dom.development.js:11276)
      at discreteUpdates$1 (react-dom.development.js:22413)
      at discreteUpdates (react-dom.development.js:3756)
      at dispatchDiscreteEvent (react-dom.development.js:5889)
  </code></pre>
  <p>EditItem componant with handleSubmit function giving error unless I refresh first:</p>
  <pre><code>import React, { useState } from 'react';
  import { db } from '../../hooks/useAuth';
  
  import {
    Button,
    Input,
    Center,
    FormControl,
    Flex,
    Heading,
  } from '@chakra-ui/react';
  
  const EditItem = ({
    user,
    items,
    setItems,
    setEditItem,
    currentList,
    editItem,
    themeObj,
  }) =&gt; {
    const checkDoc = db.collection('users').doc(user.uid);
  
    const [newDesc, setNewDesc] = useState('');
    const handleSubmit = async e =&gt; {
      e.preventDefault();
      try {
        console.log(editItem);
        console.log(newDesc);
        console.log(currentList);
        console.log(editItem.id);
        await checkDoc
          .collection(currentList)
          .doc(editItem.id)
          .update({ desc: newDesc });
  
        const editedList = items.map(item =&gt;
          item.id === editItem.id ? { ...item, desc: newDesc } : item
        );
        setItems(editedList);
        console.log(editedList);
        setNewDesc(`${editItem.desc}`);
  
        setEditItem(null);
      } catch (err) {
        console.log(err);
      } finally {
      }
    };
  
    return (
      &lt;Flex w=&quot;100%&quot; grow=&quot;1&quot; direction=&quot;column&quot; p={6}&gt;
        &lt;Center
          mb=&quot;1rem&quot;
          borderRadius=&quot;lg&quot;
          p={3}
          bg={themeObj.bg}
          color={themeObj.color}
        &gt;
          &lt;Heading size=&quot;md&quot;&gt;Edit Item Description&lt;/Heading&gt;
        &lt;/Center&gt;
        &lt;Center
          mb=&quot;1rem&quot;
          borderRadius=&quot;lg&quot;
          p={3}
          bg={themeObj.bgItem}
          color={themeObj.colorItem}
        &gt;
          {newDesc.length ? newDesc : editItem.desc}
        &lt;/Center&gt;
        &lt;form
          label=&quot;New Item Description&quot;
          onSubmit={handleSubmit}
          style={{ width: '100%' }}
        &gt;
          &lt;FormControl&gt;
            &lt;Input
              required
              variant=&quot;outline&quot;
              autoFocus
              // ref={inputRef}
              type=&quot;text&quot;
              id=&quot;newDesc&quot;
              placeholder=&quot;New Item Description&quot;
              required
              value={newDesc}
              onChange={e =&gt; setNewDesc(e.target.value)}
            /&gt;
  
            &lt;Button
              variant=&quot;solid&quot;
              mt={4}
              type=&quot;submit&quot;
              aria-label=&quot;Rename List&quot;
              color=&quot;white&quot;
              _hover={{
                background: `${themeObj.checkScheme}`,
              }}
              bg=&quot;black&quot;
            &gt;
              Update
            &lt;/Button&gt;
            &lt;Button
              variant=&quot;solid&quot;
              mt={4}
              type=&quot;button&quot;
              onClick={() =&gt; {
                setEditItem(null);
                setNewDesc(`${editItem.desc}`);
              }}
              aria-label=&quot;cancel&quot;
              color=&quot;white&quot;
              _hover={{
                background: `${themeObj.checkScheme}`,
              }}
              bg=&quot;red&quot;
            &gt;
              Cancel
            &lt;/Button&gt;
          &lt;/FormControl&gt;
        &lt;/form&gt;
      &lt;/Flex&gt;
    );
  };
  
  export default EditItem;
  </code></pre>
  <p>Dashboard component (parent to EditItem):</p>
  <pre><code>import React, { useState, useEffect } from 'react';
  import { InputGroup, Stack, Flex } from '@chakra-ui/react';
  import firebase from 'firebase/app';
  import EditItem from '../iList/EditItem';
  import Loader from '../iList/Loader';
  import AddItem from '../iList/AddItem';
  import SearchItem from '../iList/SearchItem';
  import Content from '../iList/Content';
  import Footer from '../iList/Footer';
  import { useAuth, db } from '../../hooks/useAuth';
  import 'firebase/firestore';
  
  const Dashboard = ({
    setAppTheme,
    loaderLoading,
    setLoaderLoading,
    setIsLoading,
    isLoading,
    fetchError,
    setFetchError,
    themeObj,
    currentList,
    setCurrentList,
  }) =&gt; {
    console.log(currentList);
    const { user } = useAuth();
    const [items, setItems] = useState([]);
    const [search, setSearch] = useState('');
    const [editItem, setEditItem] = useState(null);
  
    const [newItem, setNewItem] = useState('');
  
    const checkDoc = db.collection('users').doc(user.uid);
  
    const itemsCollection = db
      .collection('users')
      .doc(user.uid)
      .collection(currentList);
  
    useEffect(() =&gt; {
      checkIfInitialized();
      const getUserPrefs = async () =&gt; {
        try {
          const userList = await checkDoc.get();
          setCurrentList(userList.data().currentlist);
          setAppTheme(userList.data().currenttheme);
  
          setFetchError(null);
        } catch (err) {
          setFetchError(err.message);
  
          console.log(err.message);
        } finally {
          setLoaderLoading(false);
          setIsLoading(false);
        }
      };
      getUserPrefs();
    }, []);
  
    useEffect(() =&gt; {
  
      const getItems = async () =&gt; {
        try {
          const data = await itemsCollection.get();
  
          const listItems = data.docs.map(doc =&gt; ({
            ...doc.data(),
            id: doc.id,
          }));
          setItems(listItems);
          setFetchError(null);
        } catch (err) {
          setFetchError(err.message);
        } finally {
          setLoaderLoading(false);
        }
      };
      getItems();
    }, [currentList]);
  
    const addItem = async item =&gt; {
      const id = items.length ? Number(items[items.length - 1].id) + 1 : 1;
      console.log(id);
      const newItemDate = new Date();
      const dateStr = `${
        newItemDate.getMonth() + 1
      }/${newItemDate.getDate()}/${newItemDate.getFullYear()}`;
  
      const myNewItem = {
        id: id,
        checked: false,
        desc: item,
        date: dateStr,
      };
  
      const listItems = [...items, myNewItem];
      setItems(listItems);
      const addedDoc = db
        .collection('users')
        .doc(user.uid)
        .collection(currentList)
        .doc(`${myNewItem.id}`);
      await addedDoc
        .set({ desc: myNewItem.desc, checked: false, date: dateStr })
        .then(() =&gt; {
          console.log('Document successfully written!');
        })
        .catch(error =&gt; {
          console.error('Error writing document: ', error);
        });
    };
  
    const handleCheck = async id =&gt; {
      const listItems = items.map(item =&gt;
        item.id === id ? { ...item, checked: !item.checked } : item
      );
      setItems(listItems);
      const myItem = items.filter(item =&gt; item.id === id);
      console.log(myItem);
  
      const updatedDoc = db
        .collection('users')
        .doc(user.uid)
        .collection(currentList)
        .doc(`${id}`);
      console.log('here');
      await updatedDoc
        .update({
          checked: !myItem[0].checked,
        })
        .then(() =&gt; {
          console.log('Document successfully updated!');
        })
        .catch(error =&gt; {
          // The document probably doesn't exist.
          console.error('Error updating document: ', error);
        });
    };
    const handleDelete = async id =&gt; {
      const listItems = items.filter(item =&gt; item.id !== id);
      setItems(listItems);
      const deletedDoc = db
        .collection('users')
        .doc(user.uid)
        .collection(currentList)
        .doc(`${id}`);
      await deletedDoc
        .delete()
        .then(() =&gt; {
          console.log('Document successfully deleted!');
        })
        .catch(error =&gt; {
          console.error('Error removing document: ', error);
        });
    };
  
    const handleSubmit = e =&gt; {
      e.preventDefault();
      if (!newItem) return;
      addItem(newItem);
      setNewItem('');
    };
    const checkIfInitialized = () =&gt; {
      const docRef = db.collection('users').doc(user.uid);
  
      docRef
        .get()
        .then(doc =&gt; {
          if (doc.exists) {
            console.log('Document data:', doc.data());
          } else {
            // doc.data() will be undefined in this case
            console.log('No such document!');
            initializeUserDb();
          }
        })
        .catch(error =&gt; {
          console.log('Error getting document:', error);
        });
    };
  
    const initializeUserDb = async () =&gt; {
      const firstEntry = db.collection('users').doc(user.uid);
  
      await firstEntry
        .set({
          currentlist: currentList,
          mylists: firebase.firestore.FieldValue.arrayUnion('My List'),
          currenttheme: 'default',
          email: user.email,
        })
        .then(() =&gt; {
          console.log('currentlist successfully written!');
        })
        .catch(error =&gt; {
          console.error('Error writing document: ', error);
        });
    };
  
    return (
      &lt;&gt;
        {editItem &amp;&amp; (
          &lt;EditItem
            items={items}
            setItems={setItems}
            currentList={currentList}
            user={user}
            editItem={editItem}
            setEditItem={setEditItem}
            themeObj={themeObj}
          /&gt;
        )}
  
        {!editItem &amp;&amp; (
          &lt;&gt;
            &lt;Stack mb={3} w=&quot;100%&quot; p={3}&gt;
              &lt;InputGroup&gt;
                &lt;AddItem
                  themeObj={themeObj}
                  newItem={newItem}
                  setNewItem={setNewItem}
                  handleSubmit={handleSubmit}
                /&gt;
              &lt;/InputGroup&gt;
              &lt;InputGroup&gt;
                &lt;SearchItem
                  themeObj={themeObj}
                  search={search}
                  setSearch={setSearch}
                /&gt;
              &lt;/InputGroup&gt;
            &lt;/Stack&gt;
            &lt;Flex
              w=&quot;100%&quot;
              flexDirection=&quot;column&quot;
              flexGrow=&quot;1&quot;
              justifyContent=&quot;flex-start&quot;
              align-items=&quot;center&quot;
              overflowY=&quot;auto&quot;
            &gt;
              {(isLoading || loaderLoading) &amp;&amp; &lt;Loader /&gt;}
  
              {fetchError &amp;&amp; (
                &lt;p style={{ color: 'red' }}&gt;{`Error: ${fetchError}`}&lt;/p&gt;
              )}
  
              {!fetchError &amp;&amp; !loaderLoading &amp;&amp; !isLoading &amp;&amp; (
                &lt;Content
                  setEditItem={setEditItem}
                  themeObj={themeObj}
                  items={items.filter(item =&gt;
                    item.desc.toLowerCase().includes(search.toLowerCase())
                  )}
                  handleDelete={handleDelete}
                  handleCheck={handleCheck}
                /&gt;
              )}
            &lt;/Flex&gt;
          &lt;/&gt;
        )}
  
        &lt;Footer bg={themeObj.bg} color={themeObj.color} length={items.length} /&gt;
      &lt;/&gt;
    );
  };
  
  export default Dashboard;
  </code></pre>
  <p>firestore screenshot before refreshing app (I just created &quot;test list&quot; and two items and updating item desc doesn't work)
  <a href="https://i.stack.imgur.com/YEGKD.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YEGKD.jpg" alt="enter image description here" /></a></p>
  <p>firestore screenshot after refreshing app (updating item description works)
  <a href="https://i.stack.imgur.com/bImJ6.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bImJ6.jpg" alt="enter image description here" /></a></p>