Add user and roles race issue

Hi,

I am new to meteor and I tried creating an app using meteor with react. When I am saving a user with multiple role, I started getting race condition. The default refresh does not get the roles object but if i refersh manually I am able to get the correct roles in the newly created user. My github repo is at https://github.com/tejaser/clinic.git
and the create user method is as below:

Meteor.methods({
    "users.add": function(newUser) {
      let cResult = Accounts.createUser({
        username: newUser.username,
        email: newUser.email,
        password: newUser.password,
        profile: {
          first_name: newUser.first_name,
          last_name: newUser.last_name,
          clinic: newUser.clinic
        }
      });
      for (let index in newUser.roles) {
        Roles.addUsersToRoles(cResult, newUser.roles[index].label);
      }
      return true;
    },
    "users.addRole": function(userId, newRole) {
      Roles.addUsersToRoles(userId, newRole);
      return true;
    }
  });

Can you post the code where you retrieve the values?

This is how i am setting up data subscription:

export default withTracker(() => {
  let usersSubscription = Meteor.subscribe("allUsers");
  let rolesSubscriptioin = Meteor.subscribe("allRoles");

  const eachReady = usersSubscription.ready() && rolesSubscriptioin.ready();
  const loading = usersSubscription ? !eachReady : true;

  return {
    loading,
    users: Meteor.users.find().fetch(),
    roles: Meteor.roles.find().fetch()
  };
})(Users);

I have also put a test to know that loading is false before I start rendering. Once I get the data, I am using react to render the information. React render code is at this link.

Use state for both roles and users.

To assign the value of these state variables, you will need to use getDerivedStateFromProps()

Reason: the publications won’t return the value at the same time. Therefore, don’t expect props will contain both at the initial change. Use state to retain the value while waiting for the other

I tried your suggestion but was not sure on how to use it. Then I put a small condition to check the undefined condition in the render and it resolved the issue. Not sure if this is the correct way or not. I tried to use the new lifecycle method in below way, please let me know if it is incorrect.

constructor(props) {
    super(props);
    this.state = {
      isCreatingUsers: false,
      users: []
    };
    this.toggleCreateState = this.toggleCreateState.bind(this);
  }
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.users !== prevState.users) {
      return {
        users: nextProps.users
      };
    } else {
      return null;
    }
  }
  renderUsersTable() {
    let users = this.state.users;
    console.log(users);
    if (users.length === 0) {
      return null;
    } else {
      return users.map((user, index) => (
        <tr key={index}>
          <th scope="row">{index + 1}</th>
          <td>{user.profile.first_name}</td>
          <td>{user.profile.last_name}</td>
          <td>{user.username}</td>
          <td>{user.emails[0].address}</td>
          <td>
            {user.roles === undefined
              ? null
              : user.roles.map((role, index) => (
                  <div key={index}>
                    <span className="badge badge-pill badge-info">{role}</span>&nbsp;
                  </div>
                ))}
          </td>
        </tr>
      ));
    }
  }

You have to do it for both users and roles