Access Folders & Files From SharePoint Using Angular JS & REST API

Here we will explore pure Angular JS directives (without using jQuery or other frameworks) by accessing the SharePoint REST API. The example I have taken is accessing the folder and files from the library by the following two events:

  • On page load, accessing all the folders from the library and storing them in a dropdown box.
  • On button click event, populate the files in a table based on the selected folder from the dropdown.
So, we will make two requests to the server and render it in a page.

The following will apply a Folder collection to the Dropdown list.

HTML Snippet:
  1. <select id="lib-folder" ng-model="libFolders" ng-options=" fldr as fldr.Title for fldr in Folders" >  
  2.     <option value="">--Select Folder--</option>  
  3. </select>  
ng-options: This directive is an alternative to the ng-repeat directive. This is used to dynamically generate the list of <option> elements for the select element using the array “$scope.Folders” obtained as the result of the SharePoint REST API.

fldr.Title This is the retrieved folder name that is rendered as a value to the dynamically generated <option> element to the dropdown.

Note: If you have not used “<option value=””>--Select Folder--</option>” code, the empty option will be dynamically generated when populating the folders to the dropdown.

Script Snippet:
  1. $http({  
  2.     method: "GET",      url:_spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('DocumentLibrary')/items?$select=Id,Title ,FileDirRef,FileRef,FSObjType&$filter=FSObjType%20eq%201",  
  3.     headers: {"Accept":"application/json;odata=verbose"}  
  4. }  
  5. ).success(function(data, status, headers, config){  
  6.     $scope.Folders = data.d.results;  
  7.     $scope.libFolders = $scope.Folder[0];  
  8. }).error(function (data, status, headers, config){  
  9. });  
_spPageContextInfo.webAbsoluteUrl :_spPageContextInfo is very useful when writing JavaScript code on the SP site. This has a webAbsoluteUrl property that returns the web URL that we use to generate the REST API request URL.

REST API URL: fetches the items with the values for the following fields filtered by folder from the “DocumentLibrary” library.
_spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('DocumentLibrary')/items

View Fields:
  1. $select=Id,Title ,FileDirRef,FileRef,FSObjType  


Filter:
  1. $filter=FSObjType%20eq%201  
Returns the items, if the item type is 1 (folder).
  1. $scope.Folders = data.d.results  
The successful response assigns the folder collection array to the scope variable $scope.Folders.
The ng-options directive uses this array variable and dynamically generates the options.
  1. $scope.libFolders = $scope.Folders[0]  
Assign the first item of Folder collection array to the default value for dropdown.

Populate files based on the selected Folder:

Now we are done with the rendering of the folder list to the dropdown. To invoke the event to request the files for the selected folder, we have a button and the function “btnGetFiles()” as in the following:
<input type="button" value="Get Files" ng-click="btnGetFiles()"/>

HTML Snippet:
  1. <!-- Populate Files based on selected Folder -->  
  2. <table width="100%" cellpadding="10" cellspacing="2" class="files-table">  
  3.     <thead>  
  4.     <tr>  
  5.         <th>Title</th>  
  6.         <th>Author</th>       
  7.     </tr>  
  8.     </thead>  
  9.     <tbody>  
  10.     <tr ng-repeat="file in Files">  
  11.         <td><a href="{{file.ServerRelativeUrl}}">{{file.Name}}</a></td>  
  12.         <td>{{file.Author.Title}}</td>        
  13.     </tr>  
  14.     </tbody>  
  15. </table>  
Script Snippet:
  1. $scope.btnGetFiles = function()  
  2. {  
  3.     var selectedFolder = $scope.libFolders.FileRef+"/";  
  4.     var resturl = _spPageContextInfo.webAbsoluteUrl+"/_api/web/getfolderbyserverrelativeurl('"+selectedFolder+"')/files?$select=Name,Author/Title&$expand=Author/Title";  
  5.     $http(  
  6.     {  
  7.         method: "GET",  
  8.         url:resturl,  
  9.         headers: {"Accept":"application/json;odata=verbose"}  
  10.     }  
  11.     ).success(function(data, status, headers, config){    
  12.         $scope.Files = data.d.results;                
  13.     }).error(function (data, status, headers, config){  
  14.     });  
  15. }  
$scope.libFolders.FileRef : Returns the dropdown's selected value.

REST API URL

$expand: this option has the ability to retrieve the related properties. This is used to retrieve the author name using a single request instead of sending multiple requests.

$expand=Author/Title: file.Author.Title is to be added in HTML to retrieve the expanded value.

The successful result is stored in the scope variable “$scope.Files” and this is used in a table element to dynamically generate the rows because of the ng-repeat directive.

ng-show

If there is no files retrieved for the folder, use the ng-show directive with the condition to show the proper message as in the following:
<p ng-show="!Files.length">There are no files available under this folder.</p>

Here is the full code:
  1. <style type="text/css">  
  2. .files-table th{ background-color:#ddd; border:2px solid #fff; text-align:left}  
  3. .files-table td{ background-color:#eee; border:2px solid #fff;}  
  4. .web-heading{ padding:2px;}  
  5. </style>  
  6.   
  7. <script type="text/javascript" src="/siteassets/angular.min.js"></script>  
  8. <div ng-app="spng-App">  
  9. <h2 class="web-heading">Folder and Files</h2>  
  10. <div ng-controller="spng-WebCtrl">  
  11. <select id="lib-folder" ng-model="libFolders" ng-options="fldr as fldr.Title for fldr in Folders" >  
  12. <option value="">--Select Folder--</option>  
  13. </select>  
  14. <input type="button" value="Get Files" ng-click="btnGetFiles()"/>  
  15. <!-- Populate Files based on selected Folder -->  
  16. <table width="100%" cellpadding="10" cellspacing="2" class="files-table">  
  17. <thead>  
  18. <tr>  
  19. <th>Title</th>  
  20. <th>Author</th>   
  21. </tr>  
  22. </thead>  
  23. <tbody>  
  24. <tr ng-repeat="file in Files">  
  25. <td><a href="{{file.ServerRelativeUrl}}">{{file.Name}}</a></td>  
  26. <td>{{file.Author.Title}}</td>   
  27. </tr>  
  28. </tbody>  
  29. </table>  
  30. <p ng-show="!Files.length">There are no files available under this folder.</p>  
  31. </div>  
  32. </div>  
  1. <script type="text/javascript">  
  2. var spAppangular.module('spng-App', []);  
  3. spApp.controller('spng-WebCtrl', function($scope, $http){  
  4.   
  5. //Controller load event to append the choices with folder value to the dropdown  
  6. $http({  
  7. method: "GET",  
  8. url:_spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('DocumentSetLibrary')/items?$select=Id,Title,FileLeafRef,FileDirRef,FileRef,FSObjType&$filter=FSObjType%20eq%201",  
  9. headers: {"Accept":"application/json;odata=verbose"}  
  10. }  
  11. ).success(function(data, status, headers, config){  
  12. //Store the folder collections to the Folders scope variable  
  13. $scope.Folders = data.d.results;  
  14. //Set the default value to the dropdown  
  15. $scope.libFolders = $scope.DocumentSets[0];  
  16. }).error(function (data, status, headers, config){  
  17. });  
  18.   
  19. //Button click event to populate the files in table  
  20. $scope.btnGetFiles = function(){  
  21. //Get the selected folder from the select element  
  22. var selectedFolder = $scope.libFolders.FileRef+"/";  
  23. var resturl = _spPageContextInfo.webAbsoluteUrl+"/_api/web/getfolderbyserverrelativeurl('"+selectedFolder+"')/files?$select=Name,Author/Title&$expand=Author/Title";  
  24. $http({  
  25. method: "GET",  
  26. url:resturl,  
  27. headers: {"Accept":"application/json;odata=verbose"}  
  28. }  
  29. ).success(function(data, status, headers, config){   
  30. //Store the filecollection for the folder to the Files scope variable  
  31. $scope.Files = data.d.results;   
  32. }).error(function (data, status, headers, config){  
  33. });  
  34. }  
  35. });  
  36. </script>  
OUTPUT:



Still we have many options available in Angular JS and we will continue our exploration in this area. We will welcome the new technologies to ease the coding. Happy learning.