fix: Attendees Not Displayed in Expense View on New Expensify (Visible in Classic)#89248
fix: Attendees Not Displayed in Expense View on New Expensify (Visible in Classic)#89248Julesssss merged 9 commits intoExpensify:mainfrom
Conversation
…Visible in Classic)
|
@linhvovan29546 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
joekaufmanexpensify
left a comment
There was a problem hiding this comment.
Good for product
|
@Eskalifer1 I see there are several other places that access raw attendees. Do we need to update those as well? I think we should.
const rawAttendees = updatedTransaction.modifiedAttendees ?? updatedTransaction.comment?.attendees;
const attendees = Array.isArray(iouAttendees) ? iouAttendees : [];
const actualAttendees = isFromMergeTransaction && updatedTransaction
transaction?.comment?.attendees ?? transactionItem.attendees,
const aValue = a.comment?.attendees?.length ?? 0;
tr.comment?.attendees?.map?.((att) => ...) |
|
Good catch, i will take a deeper look today(Hope XD) |
|
@codex review |
I don't think this needs to be corrected, since this value is passed into the function, where it is later passed into another function as Line 115 in 536d1dd Which later ends up here: Line 79 in 536d1dd And we fixed this part |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 10d9de7714
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (rawAttendees && typeof rawAttendees === 'object') { | ||
| return Object.values(rawAttendees as Record<string, Attendee>); |
There was a problem hiding this comment.
Handle Map attendees in conversion helper
Update convertAttendeesToArray to explicitly support Map inputs before calling Object.values. In the problematic flow this PR targets, attendees can arrive as a Map, and Object.values(map) returns an empty array, so downstream logic still treats attendees as missing and falls back to the report owner. That means the cross-app attendee display bug remains for transactions whose attendee payload is a real Map instance.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I haven't seen Expensify use Maps for this kind of thing yet, so I don't think it's relevant.
In this specific case, we're fixing a bug where an object is passed instead of an array, so I don't think it's worth doing.
|
@linhvovan29546 PR is updated! |
| * Converts raw attendees value to an array. | ||
| * Onyx may deserialize arrays as plain objects, so both shapes are handled. | ||
| */ | ||
| function convertAttendeesToArray(rawAttendees: Attendee[] | undefined): Attendee[] { |
There was a problem hiding this comment.
I think we can update the parameter type from Attendee[] | undefined to unknown, since it can be an array, an object, or other types like a string. So we don’t need to cast the attendees when passing them to convertAttendeesToArray.
|
@Eskalifer1 Could you please resolve the conflicts? I’ll try to complete testing today. |
|
Hi @linhvovan29546! Merged main! I checked, and here we don't need to convert it to an array; we can just leave it as is: Since |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-05-05.at.16.47.41.movAndroid: mWeb ChromeScreen.Recording.2026-05-05.at.16.49.31.moviOS: HybridAppScreen.Recording.2026-05-05.at.15.39.06.moviOS: mWeb SafariScreen.Recording.2026-05-05.at.15.43.41.movMacOS: Chrome / SafariScreen.Recording.2026-05-05.at.15.20.49.mov |
Julesssss
left a comment
There was a problem hiding this comment.
Looking good, there's just the submodule conflict to resolve. I don't think we need to touch that commit number
|
@Eskalifer1 Could you please revert this change?
|
|
Hi @linhvovan29546, sorry, i have missed this message yesterday. Already done! |
|
@Eskalifer1 Eslint failed. Could you please merge main again? |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 @Julesssss has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/Julesssss in version: 9.3.68-0 🚀
Bundle Size Analysis (Sentry): |
|
No help site changes required. This PR is a pure internal bug fix — it adds a |
|
🚀 Deployed to production by https://github.com/francoisl in version: 9.3.68-3 🚀
|

Explanation of Change
Sometimes, after changing
Attendeesin OD, the backend would return the value oftransaction?.comment?.attendeesas a Map object, while the frontend expected only an array. This caused the system to fall back to the report owner instead of using the attendees returned by the backend. This PR fixes this bugFixed Issues
$#88756
PROPOSAL:#88756 (comment)
Tests
Precondition: have created workspace with enabled rules, enabled
Attendee tracking, and with a lot of members(15+)PS: Here is a link to the full video demonstrating the bug
Offline tests
N/A
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
88756-android-native.mov
Android: mWeb Chrome
88756-android-web.mov
iOS: Native
88756-ios-native.mov
iOS: mWeb Safari
88756-ios-web.mov
MacOS: Chrome / Safari
88756-web.mov