How To Use FilePicker Control Of PnP In SPFx Webpart

In this article, we will learn how to use PnP file picker control in SPFx webpart.

Background

 
With the recent popularity of SPFx, developers are required to develop some complex requirements using the SharePoint framework web part. Many of these requirements are common and need to be developed again and again. Microsoft has provided Office UI fabric react based controls which can be easily used in our SPFx webpart. Still, there are some controls that are missing in Office UI fabric, thanks to our awesome PnP initiative, community has stepped forward and developed many more controls that can be used in our SPFx solutions. 
 
You can know and read about all the controls available from PnP controls library at this link. Today, we are going to learn one of these controls 'File Picker control' and how to use it in our SPFx webpart.
 
File picker control allows us to browse and select a file from various places. Please check this link for more detail.
 
Currently supported locations
  • Recent files - tab allows selecting a file from recently modified files based on the search results.
  • Web search - tab uses Bing cognitive services to look for a file. (Only images)
  • OneDrive - tab allows selecting a file from the user's One Drive.
  • Site document libraries - tab allows selecting a file from the existing site document libraries.
  • Upload - tab allows uploading a file from a local drive.
  • From a link - tab allows pasting a link to the document.
Let's get started and create web part.
 
Step - Create SPFx solution and webpart
 
Run below commands in sequence.
 
Open a node js command prompt and create a directory for SPFx solution. 
  1. md PnPControlsDemo  
  2. cd PnPControlsDemo  
Let us now create SPFx solution and add web part to it. 
  1. yo @microsoft/sharepoint
select below options
 
How To Use FilePicker Control Of PnP In SPFx Webpart
 
Once you select all options in wizard one by one, it will take some time to generate the code structure. 
 
How To Use FilePicker Control Of PnP In SPFx Webpart
 
Now let us install required npm packages to use PnP controls. run below command.
  1. npm install @pnp/spfx-controls-react --save  
After it is completed, open same folder in Visual Studio code( you can use any other editor also).
 
Now let us modify code to use these controls.
 
Step - Passing WebPart context to React components
 
File picker requires Sharepoint site context to work with, hence we will pass it from our web part file to react components.
 
Open src\webparts\controls\components\IControlsProps.ts 
 
Modify code to below,
  1. import { WebPartContext } from '@microsoft/sp-webpart-base';      
  2. export interface IControlsProps {    
  3.   description: string;    
  4.   context: WebPartContext;      
  5. }     
Open src\webparts\controls\ControlsWebPart.ts
 
Modify render method to pass context. 
  1. public render(): void {  
  2.    const element: React.ReactElement<IControlsProps > = React.createElement(  
  3.      Controls,  
  4.      {  
  5.        description: this.properties.description,  
  6.        context:this.context  
  7.      }  
  8.    );  
  9.    ReactDom.render(element, this.domElement);  
Please note we have just added line 'context:this.context' .
 
Step - Modify the React component associated with webpart
 
Open src\webparts\controls\components\Controls.tsx
 
Import file picker control 
  1. import { FilePicker, IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker';  
Create Interface to Store State, add below code below last import statement,
  1. export interface IControlsState {    
  2.   filePickerResult:any;  
  3. }   
Modify component as below,
  1. export default class Controls extends React.Component<IControlsProps, IControlsState> {  
  2.   
  3.   constructor(props: IControlsProps, state: IControlsState) {      
  4.     super(props);      
  5.     this.state = {filePickerResult:null};      
  6.   }   
  7.   
  8. .......  
Modify the render method
 
Add below code as per your requirement,
  1. <FilePicker    
  2.   buttonLabel="Select File"    
  3.   onSave={(filePickerResult: IFilePickerResult) => { this.setState({filePickerResult }); alert(JSON.stringify(this.state.filePickerResult)); }}    
  4.   onChanged={(filePickerResult: IFilePickerResult) => { this.setState({filePickerResult });alert(JSON.stringify(this.state.filePickerResult)); }}    
  5.   context={this.props.context}    
  6. />    
Below is how final render method looks like for my sample. 
 
If you look closely, we are using onsave and onchanged method to capture select file result, set state and then alerting the object by stringify. This is just to demostrate what object is returned as selected file. Please note that this will not return base64 or actual image but only path to selected file. 
  1. public render(): React.ReactElement<IControlsProps> {    
  2.     return (    
  3.       <div className={ styles.controls }>    
  4.         <div className={ styles.container }>    
  5.           <div className={ styles.row }>    
  6.             <div className={ styles.column }>    
  7.               <span className={ styles.title }>Welcome to SharePoint!</span>    
  8.               <p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>    
  9.               <p className={ styles.description }>{escape(this.props.description)}</p>    
  10.               <a href="https://aka.ms/spfx" className={ styles.button }>    
  11.                 <span className={ styles.label }>Learn more</span>    
  12.               </a>    
  13.             </div>    
  14.           </div>    
  15.         </div>    
  16.         <br>    
  17.         </br>    
  18.         <br></br>    
  19.         <FilePicker    
  20.   buttonLabel="Select File"    
  21.   onSave={(filePickerResult: IFilePickerResult) => { this.setState({filePickerResult }); alert(JSON.stringify(this.state.filePickerResult)); }}    
  22.   onChanged={(filePickerResult: IFilePickerResult) => { this.setState({filePickerResult });alert(JSON.stringify(this.state.filePickerResult)); }}    
  23.   context={this.props.context}    
  24. />    
  25.       </div>    
  26.     );    
  27.   }     
We are done with code, now let us run it. Use gulp serve command in node js command prompt. lease note that as this control requires the ext of SharePoint site because it has to display list and libraries from SharePoint. So we will test this webpart in SharePoint workbench
 
Once, local workbench is opened in browser, open SharePoint workbench.
 
https://amazonprime.sharepoint.com/sites/familyman/_layouts/15/workbench.aspx
 
Below is output of webpart.
 
How To Use FilePicker Control Of PnP In SPFx Webpart
Click on select file button, we would see below panel opening. 
 
I have selected Site from left tab.
 
How To Use FilePicker Control Of PnP In SPFx Webpart
 
Click on any document library and we will get list of files inside that document library.
 
How To Use FilePicker Control Of PnP In SPFx Webpart
 
Click on OneDrive, you will see list of all files under current logged in user's one drive files.
 
How To Use FilePicker Control Of PnP In SPFx Webpart

Select any of file and click on open, below is when I have selected a file form one of library
 
How To Use FilePicker Control Of PnP In SPFx Webpart
 
If you look at the alert box, we can see it has returned us selected file path, filename and filenamewithoutextension etc. We can use this information to work as per our requirement. 
 

Conclusion

 
This control can be very useful if we wanted an advanced file picker control, as HTML control will only allow us to select a file from local machine. There are many configuration options available which can be used to show/hide tabs on left or configure different option of this control. 
 
Thanks for reading, hope this helps..Happy coding..!!