0

There are questions and user wanted to add new Categories in those questions. Categories like in Examination Institute and Year.
After user select questions and fields to add new categories. It first check each document in database to make sure field is not present then It creates two arrays (one for each category). After that data can be updated. I'm using async functions and for some reason validateData() return empty array for EITemp and YRTemp on First call. I have to click button twice to get array with requried data.

Main Code:

const saveData = async () => {
  //Firebase Firestore Batch to Write Multiple Documents
  const batch = writeBatch(firestore);
  if (EI.length > 0) {
    const docs = Array.from(new Set(EI))
    const EIValue = selectedFields.examInstitute
    docs.forEach(docID => {
      const DocRef = doc(firestore, "multichoice", docID);
      batch.update(DocRef, { ["ExamInstitute"]: arrayUnion(EIValue) });
      batch.update(DocRef, { ["Updated"]: timestamp });
    });

  }

  if (YR.length > 0) {
    const docs = Array.from(new Set(YR))
    const YRValue = selectedFields.year

    docs.forEach(docID => {
      const DocRef = doc(firestore, "multichoice", docID);
      batch.update(DocRef, { ["Year"]: arrayUnion(YRValue) });
      batch.update(DocRef, { ["Updated"]: timestamp });
    });
  }

  try {
    await batch.commit()
  }
  catch (error) { console.log(error) }
}
const validateData = async () => {
  setSearching(true)
  const ei = selectedFields.examInstitute;
  const yr = selectedFields.year
  var EITemp = []
  var YRTemp = []
  for await (const doc of selectedDocsID) {
    const response = await fetchDoc("multichoice", doc, false)

    const EIField = response["ExamInstitute"]
    const YRField = response["Year"]

    if (EIField == undefined) EITemp.push(doc)
    else if (EIField.includes(ei) != true) EITemp.push(doc)

    if (YRField == undefined) YRTemp.push(doc)
    else if (YRField.includes(yr) != true) YRTemp.push(doc)

  }
  setEI(EITemp)
  setYR(YRTemp)
  console.log(EI)
  console.log(YR)
  await saveData()
}
return (
<>
<Button disabled={searching} onClick={() => validateData()}>Update Data</Button>
</>
);

Fetch Doc Function:

export const fetchDoc = async (collection, slug, Seralize = true) => {
  const docRef = doc(firestore, collection, slug);
  const docSnap = await getDoc(docRef)
  if (docSnap.exists()) { return Seralize ? postToJSON(docSnap) : docSnap.data() }
  else { console.log("No such document!"); }
};

Current Result Image Link

Adam
  • 186
  • 1
  • 4
  • 20
Aly
  • 321
  • 1
  • 4
  • 15
  • what is `selectedDocsID`? – Jaromanda X Oct 15 '22 at 09:26
  • Its an array of document IDs that user selected. – Aly Oct 15 '22 at 09:27
  • OK, so it's an *async iterable object* - not that it matters, `for await ... of` works on regular iterables as well, just odd to see `for await of` being used on an Array – Jaromanda X Oct 15 '22 at 09:30
  • Also, what you haven't described is the actual issue ... you say *Not Working* ... you say *it's returning an empty Array* .... what function is doing that? – Jaromanda X Oct 15 '22 at 09:32
  • `validateData()` return empty array for `EITemp` and `YRTemp` on First call. I have to click button twice to get array with requried data – Aly Oct 15 '22 at 09:34
  • `setEI(EITemp); setYR(YRTemp); console.log(EI); console.log(YR)` Are you expecting these `set` calls to change what gets logged out on the lines immediately after? If so, that's not going to happen. https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately – Nicholas Tower Oct 15 '22 at 09:45

0 Answers0