invrt
invrt

Reputation: 709

useEffect hook to update state from a function that returns a promise

I have a function that returns an object.

It looks like this

const aggResults = data => {
  const { surveyName, questionId } = data
  const db = firebase.firestore()
  const surveyData = db.collection('surveys').doc(surveyName)

  return surveyData.onSnapshot(doc => {
    console.log('test', doc.data().aggResults[questionId])
    return doc.data().aggResults[questionId]
  })
}

Frome the same file, I call my function like this

 {
      ...
      output: {
        ...
        function: () => aggResults({ surveyName: '...', questionId: '...' }),
      },
    },

In a separate file, I want to update my state based with what aggResults returns.

I have used a useEffect hook to do this

const [data, updateData] = useState({})
  useEffect(() => {
    if (!_.isUndefined(question.output)) {
      question.output.function().then(res => updateData(res))
    } else {
      console.log('q', question.output)
    }
  }, [question])

The error I'm getting at the moment is TypeError: question.output.function().then is not a function

Where am I going wrong?

Upvotes: 0

Views: 26

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317372

onSnapshot doesn't return a promise. It returns an unsubscribe function that you call to remove the listener from the DocumentReference. You can see an example of this in the documentation. When you call question.output.function(), it is going to return you this unsubscribe function.

Snapshot listeners are for receive updates to a document as it changes over time. If you're trying to do a single query without listening for ongoing changes, you should use get() instead of onSnapshot(), as shown in the documentation. get() returns a promise that resolves with a DocumentSnapshot contains the document data.

Upvotes: 1

Related Questions