-
Hey guys, after many tries I come here for help. The first fetches the list of users and I transform using export const { selectById: selectUserFromListById, selectAll: selectAllUsers } =
adminUsersAdapter.getSelectors(
(state: Store) => selectAdminUsersData(state) ?? initialState
); What I want to do is the merge the two results into just one select because I need information from both. RTK slice: const adminUsersAdapter = createEntityAdapter<EntityUser>({});
const initialState = adminUsersAdapter.getInitialState();
export const userManagementSlice = sqaApi.injectEndpoints({
endpoints: (build) => ({
getAdminUsers: build.query<EntityState<EntityUser>, void>({
query: () => '/admin/users?limit=999',
providesTags: [
{
type: 'AdminUsers',
id: 'LIST',
},
],
transformResponse: (responseData: GetAdminUsersResponse) => {
const users: EntityUser[] = responseData.map((user) => ({
userName: user.username,
id: user.ref?.split('/')[1],
name: user.label,
role: translateRole(user.role_label),
roleSqid: user.role_sqid,
email: user.email,
mobilePhone: user.phone_number,
userDomain: 'Group BE',
lastUpdate: new Date().toString(),
sqid: user.sqid,
ref: user?.ref.split('/')[1],
sites: [],
siteGroups: [],
// using defaults that will be overwritten
// when fetching the individual user
timezone: 'Europe/Brussels',
locale: 'en_EN',
}));
return adminUsersAdapter.setAll(initialState, users);
},
}),
getAdminUser: build.query<EntityUser, string>({
query: (userId) => `/admin/users/${userId}`,
providesTags: (_res, _err, userId) => [
{
type: 'AdminUsers',
id: userId,
},
],
transformResponse: (responseData: GetAdminUserResponse, meta, arg) => {
const user: Partial<EntityUser> = {
sqid: responseData.actor.sqid,
ref: responseData.actor.ref.split('/')[1],
id: arg,
timezone: responseData.preferences.timezone.user_timezone,
locale: responseData.preferences.locale,
userName: responseData.actor.username,
sites: responseData.domain.site?.map((site) => site.sqid) ?? [],
siteGroups:
responseData.domain.site_group?.map((group) => group.sqid) ?? [],
};
return user as unknown as EntityUser;
},
}),
}),
}); What I tried
export const addAdminUserDetailsToListListener = startAppListening({
matcher: userManagementSlice.endpoints.getAdminUser.matchFulfilled,
effect: ({ payload }, listenerApi) => {
listenerApi.dispatch(
userManagementSlice.util.updateQueryData(
'getAdminUsers',
undefined,
(draft) => {
draft = adminUsersAdapter.upsertOne(draft, payload);
return draft;
}
)
);
},
}); For some reason, the
const selectUserId = (state: Store, userId: string) => userId;
const selectApiCache = (state: Store) =>
state[userManagementSlice.reducerPath].queries;
export const selectAdminUserById = createSelector(
[selectApiCache, selectUserId],
(apiCache, userId) => {
const listEntry =
(apiCache['GetAdminUsers(undefined)']?.data as EntityState<EntityUser>)
?.entities?.[userId] ?? {};
const individualEntry = apiCache[`GetAdminUser(${userId})`]
?.data as EntityUser;
return { ...listEntry, ...individualEntry };
}
); but for some reason this select returns empty I am out of ideas for this scenario. How can |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Update: The listener worked but I was using wrong update method with listenerApi.dispatch(
userManagementSlice.util.updateQueryData(
'getAdminUsers',
undefined,
(draft) => {
adminUsersAdapter.upsertOne(draft, payload);
}
)
); Also for my case, this was sometimes not working because of race condition between the two calls so I need to add an |
Beta Was this translation helpful? Give feedback.
Update:
The listener worked but I was using wrong update method with
entityAdapter
. Correct usage:Also for my case, this was sometimes not working because of race condition between the two calls so I need to add an
initiate
orprefetch
for theadmin/users
call so that the cache entry is always in place