Articles about European Sharepoint Hosting Service
SharePoint Folder Operations Demo Using PnP JS In React Based SPFx Webpart
In this article, we will learn how to perform operations like add, copy, move, and delete folders using the PnP library in the SPFx web part. PnPJs is an awesome library that providers wrappers around SharePoint REST API so that we as the developer do not have to write repetitive code and also worry about details on how to pass headers, data, etc. It is not only limited to SharePoint but we can also use it to call graph and office 365 API. As this library comes as an npm package, it can be used for any node js and javascript-based projects. Today we will use it in the context of the SharePoint Framework.
Let’s start by creating an SPFx web part. Go to the command prompt and directory where you want to create your SPFx solution.
1 2 3 |
md pnpfolderoperations cd pnpfolderoperations yo @microsoft<span class="token operator">/</span>sharepoint |
Use the below options to create a new SPFx solution. (we will be using React framework, just because it is really cool).
Once the solution is created you can open the project in your favorite editor(mine is VS code).
Now let’s install pnp library, use the below command in the node js command prompt.
1 |
npm install @pnp<span class="token operator">/</span>sp |
For the sake of simplicity, we won’t be using any fancy UI ..we will just create buttons and perform different operations on click of the buttons.
Let’s start making code changes, go-to editor.
Pass SharePoint Context to React component
1. Open src\webparts\foldersdemo\components\IFoldersdemoProps.ts
Create context properties to hold SharePoint context.
1 2 3 4 5 6 |
<span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> WebPartContext <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">"@microsoft/sp-webpart-base"</span><span class="token punctuation">;</span> <span class="token keyword module keyword-export">export</span> <span class="token keyword keyword-interface">interface</span> <span class="token class-name">IFoldersdemoProps</span> <span class="token punctuation">{</span> description<span class="token operator">:</span> string<span class="token punctuation">;</span> context<span class="token operator">:</span><span class="token maybe-class-name">WebPartContext</span> <span class="token punctuation">}</span> |
2. Go to src\webparts\foldersdemo\FoldersdemoWebPart.ts
1 2 3 4 5 6 7 8 9 10 |
<span class="token keyword keyword-public">public</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword keyword-void">void</span> <span class="token punctuation">{</span> <span class="token keyword keyword-const">const</span> element<span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">ReactElement</span></span><span class="token operator"><</span><span class="token maybe-class-name">IFoldersdemoProps</span><span class="token operator">></span> <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token method function property-access">createElement</span><span class="token punctuation">(</span> Foldersdemo<span class="token punctuation">,</span> <span class="token punctuation">{</span> description<span class="token operator">:</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">properties</span><span class="token punctuation">.</span><span class="token property-access">description</span><span class="token punctuation">,</span> context<span class="token operator">:</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">context</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> ReactDom<span class="token punctuation">.</span><span class="token method function property-access">render</span><span class="token punctuation">(</span>element<span class="token punctuation">,</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">domElement</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Setup PnP in React Component
1. Go to src\webparts\foldersdemo\components\Foldersdemo.tsx
Import library, you can do selective import but for this demo, we will be loading all presets.
1 |
<span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> sp<span class="token punctuation">,</span> IFolders<span class="token punctuation">,</span> Folders <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">"@pnp/sp/presets/all"</span><span class="token punctuation">;</span> |
2. In the same file, let’s initialize the PnP SP object with context. Add a constructor in your react class.
1 2 3 4 5 6 |
<span class="token function">constructor</span> <span class="token punctuation">(</span><span class="token parameter">props<span class="token operator">:</span><span class="token maybe-class-name">IFoldersdemoProps</span><span class="token punctuation">,</span>state<span class="token operator">:</span><span class="token punctuation">{</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-super">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> sp<span class="token punctuation">.</span><span class="token method function property-access">setup</span><span class="token punctuation">(</span><span class="token punctuation">{</span> spfxContext<span class="token operator">:</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">context</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Add required logic in React component
1. Go to src\webparts\foldersdemo\components\Foldersdemo.tsx
Replace render method with below code,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<span class="token keyword keyword-public">public</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">ReactElement</span></span><span class="token operator"><</span><span class="token maybe-class-name">IFoldersdemoProps</span><span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword control-flow keyword-return">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span><span class="token maybe-class-name">React</span><span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">Fragment</span></span><span class="token operator">></span> <span class="token operator"><</span>div className<span class="token operator">=</span><span class="token punctuation">{</span> styles<span class="token punctuation">.</span><span class="token property-access">foldersdemo</span> <span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span>div className<span class="token operator">=</span><span class="token punctuation">{</span> styles<span class="token punctuation">.</span><span class="token property-access">container</span> <span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span>div className<span class="token operator">=</span><span class="token punctuation">{</span> styles<span class="token punctuation">.</span><span class="token property-access">row</span> <span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span>div className<span class="token operator">=</span><span class="token punctuation">{</span> styles<span class="token punctuation">.</span><span class="token property-access">column</span> <span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span>span className<span class="token operator">=</span><span class="token punctuation">{</span> styles<span class="token punctuation">.</span><span class="token property-access">title</span> <span class="token punctuation">}</span><span class="token operator">></span><span class="token maybe-class-name">Welcome to SharePoint</span><span class="token operator">!</span><span class="token operator"><</span><span class="token operator">/</span>span<span class="token operator">></span> <span class="token operator"><</span>p className<span class="token operator">=</span><span class="token punctuation">{</span> styles<span class="token punctuation">.</span><span class="token property-access">subTitle</span> <span class="token punctuation">}</span><span class="token operator">></span><span class="token maybe-class-name">Folder Operations Demo using PnP</span><span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span>br<span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token maybe-class-name">Stack horizontal tokens</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>childrenGap<span class="token operator">:</span><span class="token number">40</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span><span class="token maybe-class-name">PrimaryButton text</span><span class="token operator">=</span><span class="token string">"Create Folders"</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=></span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access">createFolder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token maybe-class-name">PrimaryButton text</span><span class="token operator">=</span><span class="token string">"Rename Folder"</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=></span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access"><span class="token maybe-class-name">RenameFolder</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token maybe-class-name">PrimaryButton text</span><span class="token operator">=</span><span class="token string">"Copy Folder"</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=></span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access"><span class="token maybe-class-name">CopyFolder</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token maybe-class-name">PrimaryButton text</span><span class="token operator">=</span><span class="token string">"Move Folder"</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=></span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access"><span class="token maybe-class-name">MoveFolder</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span><span class="token maybe-class-name">Stack</span><span class="token operator">></span> <span class="token operator"><</span>br<span class="token operator">/</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span><span class="token maybe-class-name">React</span><span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">Fragment</span></span><span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
2. Now let’s add the required method which will be called on respective buttons.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<span class="token keyword keyword-private">private</span> <span class="token keyword keyword-async">async</span> <span class="token function">createFolder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword keyword-var">var</span> libraryName <span class="token operator">=</span> <span class="token string">"DemoLibrary"</span><span class="token punctuation">;</span> <span class="token keyword keyword-var">var</span> newFolderResult <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">add</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> newFolderResult <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">add</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> newFolderResult <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">add</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder3"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> newFolderResult <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">add</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder4"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">"Four folders created"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Four folders created"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword keyword-private">private</span> <span class="token keyword keyword-async">async</span> <span class="token function"><span class="token maybe-class-name">RenameFolder</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword keyword-var">var</span> libraryName <span class="token operator">=</span> <span class="token string">"DemoLibrary"</span><span class="token punctuation">;</span> <span class="token keyword keyword-const">const</span> folder <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder1"</span><span class="token punctuation">)</span> <span class="token keyword keyword-const">const</span> item <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> folder<span class="token punctuation">.</span><span class="token method function property-access">getItem</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword keyword-const">const</span> result <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> item<span class="token punctuation">.</span><span class="token method function property-access">update</span><span class="token punctuation">(</span><span class="token punctuation">{</span> FileLeafRef<span class="token operator">:</span> <span class="token string">"RenamedCreatedFolder1"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Folder 'CreatedFolder1' renamed to 'RenamedCreatedFolder1'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword keyword-private">private</span> <span class="token keyword keyword-async">async</span> <span class="token function"><span class="token maybe-class-name">CopyFolder</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword keyword-var">var</span> libraryName <span class="token operator">=</span> <span class="token string">"DemoLibrary"</span><span class="token punctuation">;</span> <span class="token keyword keyword-var">var</span> relativeUrl <span class="token operator">=</span> <span class="token string">"/sites/TSwithoutGroup/DemoLibrary/CreatedFolder3/newfoldername"</span> <span class="token keyword keyword-const">const</span> folder <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder2"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">copyTo</span><span class="token punctuation">(</span>relativeUrl<span class="token punctuation">)</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Copied Folder 'CreatedFolder2' to 'CreatedFolder3' with name 'newfoldername'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword keyword-private">private</span> <span class="token keyword keyword-async">async</span> <span class="token function"><span class="token maybe-class-name">MoveFolder</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword keyword-var">var</span> libraryName <span class="token operator">=</span> <span class="token string">"DemoLibrary"</span><span class="token punctuation">;</span> <span class="token keyword keyword-var">var</span> relativeUrl <span class="token operator">=</span> <span class="token string">"/sites/TSwithoutGroup/DemoLibrary/CreatedFolder3/CreatedFolder4"</span> <span class="token keyword keyword-const">const</span> folder <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> sp<span class="token punctuation">.</span><span class="token property-access">web</span><span class="token punctuation">.</span><span class="token property-access">rootFolder</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span>libraryName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">folders</span><span class="token punctuation">.</span><span class="token method function property-access">getByName</span><span class="token punctuation">(</span><span class="token string">"CreatedFolder4"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">moveTo</span><span class="token punctuation">(</span>relativeUrl<span class="token punctuation">)</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Moved Folder 'CreatedFolder4' to 'CreatedFolder3' with name 'CreatedFolder4'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
So we are done with changes, let’s test it…run ‘gulp serve’ and open SharePoint workbench.aspx
Let us first see how the library is looking before doing any operations.
Click on Create Folders,
Let us see the results of Create Folders operation. It has created 4 folders.
Click on Rename Folder.
This will rename the folder as specified.
Click on Copy Folder.
The folder has been copied to the destination.
Click on the Move folder.
We can see the folder has been moved.
Conclusion
In this article, we have explored the below concepts.
- SPFx React-based web part
- Using PnPJS library in SPFx web part
- CRUD operations on folders in SharePoint using PnP JS
Print article | This entry was posted by Peter on November 4, 2021 at 2:19 am, and is filed under Other Related Post. Follow any responses to this post through RSS 2.0. Both comments and pings are currently closed. |