microsoft-graph-toolkit
microsoft-graph-toolkit copied to clipboard
When using <PeoplePicker selectionMode={'multiple'} selectedPeople={Array of emails} I get no name and picture and error
Describe the bug My code is
<PeoplePicker placeholder={'Up to 50 people'} selectionMode={'multiple'}
id="AdditionalRecipients" disabled={!dpcRequest.LockedToMe}
selectedPeople={graphIds}//defaultSelectedUserIds={graphIds} //
showMax={50}
selectionChanged={onAdditionalRecipientsChanged}
/>
To Reproduce populate graphIds with array of emails 4. See error
Uncaught TypeError TypeError: Cannot use 'in' operator to search for 'groupTypes' in [email protected]
at n (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:553:541)
at <anonymous> (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:553:1964)
at loadState (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:553:1706)
at <anonymous> (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:13919)
at <anonymous> (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:11789)
at c (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:11537)
at <anonymous> (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:13805)
at <anonymous> (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:13786)
at <anonymous> (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:11789)
at c (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:11537)
at requestStateUpdate (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:13513)
at firstUpdated (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:982:13176)
at performUpdate (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:889:18131)
at _enqueueUpdate (C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:889:17642)
n @ C:\Users\ogal\source\repos\SPFx\SPFx14\DPCOneJobScreen\node_modules\@microsoft\mgt-spfx\dist\mgt-library_ec012d888c08087c4879.js:553:541
Expected behavior Show user picture and name in people picker
Screenshots
Shows
Environment (please complete the following information):
- OS: [windows]
- Browser [chrome]
- Framework [react ]
- Context [SharePoint]
- Version [e.g. 2.4]
- Provider [ spfx
when using array of graph IDs nothing shows
Hello Ofer-Gal, thank you for opening an issue with us!
I have automatically added a "needs triage" label to help get things started. Our team will analyze and investigate the issue, and escalate it to the relevant team if possible. Other community members may also look into the issue and provide feedback 🙌
I just replied to your question, can you validate this is an array and not an enumerable or collection? If you use Array.from()
, does it work?
graphIds is a state variable which is an array. How would I use Array.from()?
Array.from(graphIds); ?
I will try later.
Exactly!
Now with version following the doc defaultSelectedUserIds expects a string "a string of comma-separated Microsoft Graph user IDs" so when I set a state variable as string. Typescript complaines that defaultSelectedUserIds should be a string array Important to mention this is React!
import { PeoplePicker } from '@microsoft/mgt-react/dist/es6/spfx';
later
<PeoplePicker placeholder={'Up to 50 people'} selectionMode={'multiple'}
id="AdditionalRecipients" disabled={!dpcRequest.LockedToMe}
defaultSelectedUserIds={[graphIds]} // {graphIds} is an error // selectedPeople={graphIds}
showMax={50}
selectionChanged={onAdditionalRecipientsChanged}
/>
Can I get a working example where the defaultSelectedUserIds or selectedPeople is populate from a state variable and not hard coded?
Thank you
I also started seeing the following in the console:
Uncaught DOMException DOMException: Failed to execute 'get' on 'IDBObjectStore': No key or key range specified.
anything I can do about it?
Just to confirm. Your array of graphIds
is an array of ['GUID', 'GUID', ...]
?
Yes it is
With this repro, I can't get your issues... Is there anything that impacts it?
https://stackblitz.com/edit/mgt-1644?file=App.tsx
Guess the only difference is that my implementation is in a SPFx webpart and real 365 tenant rather than "MockProvider" My provider init in the ...webpart.ts is:
if (!Providers.globalProvider) {
Providers.globalProvider = new SharePointProvider(this.context);
}
Actually, I managed to change it and show the issue on the forked https://stackblitz.com/edit/mgt-1644-khlofu?file=App.tsx See how when the array is created on the " React.useEffect" and saved into state variable "startPeople" to do it like in the code that calls SharePoint and Graph to get the users, then when using the startPeople for defaultSelectedUserIds the users do not show
See if you can fix it :-) Thanks for the help
Now I understand your point. And this feels like a nasty React + MGT bug. @musale / @gavinbarron / @Mnickii anybody can confirm the bug and how this doesn't work with the useEffect on the initial load? When following through the callstack I see the defaultSelectedUserIds being empty, then nothing... It feels like the DOM doesn't reload when useEffect is hit. Is it a misuse of the useEffect or MGT doesn't trigger?
Interesting. This seems to be a conflation of defaultSelectedUserIds and selectedUsers. Based on my experimentation defaultSelectedUserIds is only used during initialization.
Compare these two behaviors: Defer loading until default list populated - defaultSelectedUserIds Load immediately - update the value bound to selectedPeople
It feels like this behavior is by design to me @Ofer-Gal does this resolve your issue? If not, can you give us a bit more detail around your scenario?
Both have the await sleep(5000);
and both seem to fix at first. when I I clicked Load immediately - update the value bound to selectedPeople a second time, I see just icons.
I will try the first method in the web part later.
Thanks for the help
Yeah, the selectedPeople option expects an array of person type objects, not just an array of ids, so I made a shameless hack in the interests of showing the functionality, note how the array contains objects with the id property set.
@Ofer-Gal I'm going to mark this as closed now, please feel free to re-open if you need to.
In my SPFx Web Part (now MGT 2.6.0) it only show correctly when using literals like in the Demo.
defaultSelectedUserIds={['67bfd792-fe22-477c-9b11-4c1c63237b4e','d661d903-3fd0-496e-a356-cb96ecd10e60','[email protected]']}
When using variables
const [graphIds, setGraphIds] = React.useState(null);
const others:string[] ="'67bfd792-fe22-477c-9b11-4c1c63237b4e','d661d903-3fd0-496e-a356-
cb96ecd10e60','[email protected]'".split(",");
setGraphIds(others)
then in the component
defaultSelectedUserIds={graphIds}
It shows nothing.
Do you want to leave it only good for demos? :-) Actual usage will always involve using variables, and with multi, it will always be an array .
Thanks any way
Interestingly enough, this works using our Web Component, but it has a hard time with React, probably because of the way it seems to only support initialization. @gavinbarron what if we reopen this and look in details later? This seems like a valid scenario as I would say devs should not hardcode user ids in their code 😎
@Ofer-Gal thank you for calling out this challenge. This has to be addressed. We can't ship code that isn't useful in production scenarios as you rightly point out.
@sebastienlevert yes, this is a real-world issue and we need to resolve it.
Hello @sebastienlevert is this fix going to be in Milestone 2022-12 and if so, do you have an estimate on when this will be released? Many thanks
@pwmather This was not delivered in the 2022-12 milestone and has been reprioritized to be part of the v3.0.0 milestone. We expect to be in a preview state for v3.0.0 by the end of February 2023
Thank you for the update @gavinbarron
Oh my gosh, I'm sorry I missed this earlier.
The react code here doesn't work because the defaultSelectedUserIds
is not set on the initial render.
const [graphIds, setGraphIds] = React.useState(null);
const others:string[] ="'67bfd792-fe22-477c-9b11-4c1c63237b4e','d661d903-3fd0-496e-a356-
cb96ecd10e60','[email protected]'".split(",");
setGraphIds(others);
return (<PeoplePicker placeholder={'Up to 50 people'} selectionMode={'multiple'}
id="AdditionalRecipients" disabled={!dpcRequest.LockedToMe}
defaultSelectedUserIds={graphIds}
showMax={50}
selectionChanged={onAdditionalRecipientsChanged}
/>
What's happening is that the state of graphIds
is null on the initial render. The call to setGraphIds(others)
updates the value of graphIds
after the first render of the component and enqueues another render, the React docs are not very good at noting this subtle behavior IMO and it's a super easy mistake to make, https://reactjs.org/docs/hooks-reference.html#usestate
I would avoid rendering the PeoplePicker until after there is content in the graphIds array to be passed as the default value. Seb has made a helpful demo on stack blitz showing this behavior: https://stackblitz.com/edit/mgt-1644-dsej75?file=App.tsx
Now, there's a legitimate bug here in that when updating the value of defaultSelectedUserIds
doesn't trigger an update to the state of the component and a fetch to graph and the code as above will correctly render the selected users after a user gives focus to the input box, which does trigger the state update using the updated set of defaultSelectedUserIds
Thanks. I will try this.
Works Thx