Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async/await in componentDidMount to load in correct order

I am having some troubles getting several functions loading in the correct order. From my code below, the first and second functions are to get the companyID companyReference and are not reliant on one and another.

The third function requires the state set by the first and second functions in order to perform the objective of getting the companyName.

async componentDidMount() {
    const a = await this.companyIdParams();
    const b = await this.getCompanyReference();
    const c = await this.getCompanyName();
    a;
    b;
    c;
  }

  componentWillUnmount() {
    this.isCancelled = true;
  }

  companyIdParams = () => {
    const urlString = location.href;
    const company = urlString
      .split('/')
      .filter(Boolean)
      .pop();
    !this.isCancelled &&
      this.setState({
        companyID: company
      });
  };

  getCompanyReference = () => {
    const { firebase, authUser } = this.props;
    const uid = authUser.uid;
    const getUser = firebase.user(uid);
    getUser.onSnapshot(doc => {
      !this.isCancelled &&
        this.setState({
          companyReference: doc.data().companyReference
        });
    });
  };

  getCompanyName = () => {
    const { firebase } = this.props;
    const { companyID, companyReference } = this.state;
    const cid = companyID;
    if (companyReference.includes(cid)) {
      const getCompany = firebase.company(cid);
      getCompany.onSnapshot(doc => {
        !this.isCancelled &&
          this.setState({
            companyName: doc.data().companyName,
            loading: false
          });
      });
    } else if (cid !== null && !companyReference.includes(cid)) {
      navigate(ROUTES.INDEX);
    }
  };

How can I achieve this inside componentDidMount?

like image 233
Darren Avatar asked Dec 30 '25 01:12

Darren


1 Answers

setState is asynchronous, so you can't determinate when the state is updated in a sync way.

1) I recommend you don't use componentDidMount with async, because this method belongs to react lifecycle.

Instead you could do:

componentDidMount() {
  this.fetchData();
}

fetchData = async () => {
  const a = await this.companyIdParams();
  const b = await this.getCompanyReference();
  const c = await this.getCompanyName();
}

2)

The companyIdParams method doesn't have a return, so you are waiting for nothing. If you need to wait I would return a promise when setState is finished;

companyIdParams = () => {
  return new Promise(resolve => {
    const urlString = location.href;
    const company = urlString
      .split('/')
      .filter(Boolean)
      .pop();
    !this.isCancelled &&
      this.setState({
        companyID: company
      }, () => { resolve() });
  });
};

The same for getCompanyReference:

getCompanyReference = () => {
  return new Promise(resolve => {
    const { firebase, authUser } = this.props;
    const uid = authUser.uid;
    const getUser = firebase.user(uid);
    getUser.onSnapshot(doc => {
      !this.isCancelled &&
        this.setState({
          companyReference: doc.data().companyReference
        }, () => { resolve() });
    });
  });
};

3)

If you want to parallelize the promises, you could change the previous code to this:

const [a, b] = await Promise.all([
  await this.companyIdParams(),
  await this.getCompanyReference()
]);

4)

According to your code, the third promise is not a promise, so you could update (again ;) the above code:

const [a, b] = .....
const c = this.getCompanyName()

EDIT: the bullet points aren't steps to follow

like image 194
David Táboas Avatar answered Jan 01 '26 17:01

David Táboas