-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[MM-12743] Migrate loadProfilesAndTeamMembers of user actions into redux-style #2017
[MM-12743] Migrate loadProfilesAndTeamMembers of user actions into redux-style #2017
Conversation
actualActions = testStore.getActions(); | ||
expect(actualActions[0].args).toEqual(expectedActions[0].args); | ||
expect(actualActions[0].type).toEqual(expectedActions[0].type); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, can't do much testing as I'm not able to spy on below codeblock. Maybe, it's something to think about on how to do it.
if (data) {
loadTeamMembersForProfilesList(data, newTeamId, success);
doDispatch(loadStatusesForProfilesList(data));
}
actions/user_actions.jsx
Outdated
const {data} = await UserActions.getProfilesInTeam(teamId, page, perPage)(dispatch, getState); | ||
loadTeamMembersForProfilesList(data, teamId, success); | ||
dispatch(loadStatusesForProfilesList(data)); | ||
export function loadProfilesAndTeamMembers(page, perPage, teamId = getCurrentTeamId(getState()), success) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the default argument here? That's using the global state which is going to get confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry about this, I thought I removed it.
@@ -40,10 +40,15 @@ export async function switchFromLdapToEmail(email, password, token, ldapPassword | |||
} | |||
} | |||
|
|||
export async function loadProfilesAndTeamMembers(page, perPage, teamId = getCurrentTeamId(getState()), success) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the success callback and have callers use .then(success)
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're passing it to loadTeamMembersForProfilesList
and you're not changing that function right now, we can get around that for now by explicitly returning an explicit Promise instead of using an async function for the body of the action like
function doSomething() {
return (dispatch, getState) => {
return new Promise((resolve) => {
loadTeamMembersForProfilesList(resolve);
});
};
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @hmhealey! I managed to remove success
and error
callbacks (although error
callback is really not being used elsewhere). Could you please take a look again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really surprised. We probably just added success and error for consistency with all the other actions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is working properly, I'm ok with it, but looks like this is not exactly the same behavior under the hood. Here, the promise is resolved when the getProfilesInTeam
is success, in the previous implementation it the success call was made after the loadTeamMembersForProfilesList
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's working properly after testing several cases, and yes, it's a bit different since it only dispatches loadTeamMembersForProfilesList
and loadStatusesForProfilesList
after success call in getProfilesInTeam
which I believe makes sense.
The loadProfilesAndTeamMembers
returns {data: true}
which can be consumed when a callback is necessary.
} | ||
} | ||
|
||
export function loadChannelMembersForProfilesMap(profiles, channelId = getCurrentChannelId(getState()), success, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
loadChannelMembersForProfilesMap
is not being used elsewhere.
actions/user_actions.jsx
Outdated
const channelIdParam = channelId || getCurrentChannelId(state); | ||
const {data} = await doDispatch(UserActions.getProfilesInChannel(channelIdParam, page, perPage)); | ||
if (data) { | ||
doDispatch(loadTeamMembersForProfilesList(data, teamIdParam)).then(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use await
there (I think) instead of .then
.
actions/user_actions.jsx
Outdated
|
||
loadTeamMembersForProfiles(list, teamId, success, error); | ||
doDispatch(getTeamMembersByIds(teamIdParam, userIdsToLoad)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, the .then
is called before the getTeamMembersByIds
returns, with the other implementation is called after it returns. It can be solved adding an await
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I'll add it.
actions/user_actions.jsx
Outdated
const state = doGetState(); | ||
const teamIdParam = teamId || getCurrentTeamId(state); | ||
const channelIdParam = channelId || getCurrentChannelId(state); | ||
doDispatch(loadTeamMembersForProfilesList(profiles, teamIdParam)).then(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use await
here, I think.
actions/user_actions.jsx
Outdated
success(result.data); | ||
} | ||
}); | ||
doDispatch(getChannelMembersByIds(channelIdParam, list)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't await here, we are returning on .then
before the getChannelMembersById
action is run.
@@ -116,7 +115,12 @@ export default class SystemUsers extends React.Component { | |||
} else if (teamId === SearchUserTeamFilter.NO_TEAM) { | |||
loadProfilesWithoutTeam(0, Constants.PROFILE_CHUNK_SIZE, this.loadComplete); | |||
} else { | |||
loadProfilesAndTeamMembers(0, Constants.PROFILE_CHUNK_SIZE, teamId, this.loadComplete); | |||
this.props.actions.loadProfilesAndTeamMembers(0, Constants.PROFILE_CHUNK_SIZE, teamId).then(({data}) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you going to use async
you should use await
here, if not, you can leave the function without async
and handle here the promise. I prefer the former option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I totally missed that. I'll use the async/await.
// Paging isn't supported while searching | ||
|
||
if (this.props.teamId === SearchUserTeamFilter.ALL_USERS) { | ||
loadProfiles(page + 1, USERS_PER_PAGE, this.loadComplete); | ||
} else if (this.props.teamId === SearchUserTeamFilter.NO_TEAM) { | ||
loadProfilesWithoutTeam(page + 1, USERS_PER_PAGE, this.loadComplete); | ||
} else { | ||
loadProfilesAndTeamMembers(page + 1, USERS_PER_PAGE, this.props.teamId, this.loadComplete); | ||
this.props.actions.loadProfilesAndTeamMembers(page + 1, USERS_PER_PAGE, this.props.teamId).then(({data}) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, if this not propage the async to other functions, makes sense to keep this function consistent with the loadDataForTeam
function. I mean, set the function as async
and use await
instead of .then
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, changing since I'm 0/5 with that and yours make sense 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general looks good to me, but I see some inconsistencies and subtle changes of behavior in the async requests. Maybe I'm wrong, but I prefer to clarify it before we merge :)
Thanks @jespino for your feedbacks, please take a look again. |
Summary
This PR migrates the following user_actions into redux-style:
and removed the following since it's not being used elsewhere:
Affected Area:
@DHaussermann Above were tested and looks good.
Ticket Link
Jira ticket: MM-12743
Checklist
make check-style
to check for style errors (required for all pull requests)make test
to ensure unit and component tests passed