Find first level subsites Sharepoint 2013 with Rest API

Today I had to complete a task in a custom branding SharePoint site : inject a simple webpart in a page, where the user could see all the 1st level subsites of the current site.

So my first thought was to add a snippet editor web part and write some angular using Rest API. First I had to write the html part injecting AngularJS

     <div ng-controller="subsitesCtrl as vm">
       <ul>
         <li ng-repeat="site in vm.sites">
            <a ng-href="{{site.ServerRelativeUrl}}">{{site.Title}}</a></li>
       </ul>
     </div>

Then I had to implement the JavaScript part

(function () {
           "use strict";

        angular
            .module("centralModule")
            .controller("subsitesCtrl",
                        ["$http", subsitesCtrl]);

        function subsitesCtrl($http) {
            var vm = this;

            $http({
                method: 'GET',
                url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/webinfos?$select=Title,ServerRelativeUrl&$orderby=Title",
                headers: { "Accept": "application/json;odata=verbose" }
            }).success(function (data, status, headers, config) {

                vm.sites = data.d.results;
            }).error(function (data, status, headers, config) {
                alert("error retrieving subsites");
            });

        }
    })();

As you can see I made a call to Rest API using webinfos
/_api/web/webinfos?$select=Title,ServerRelativeUrl&$orderby=Title

All seemed to work nice but when I tried to visit this page with a user who had no access to some of the websites then an error occurred.After some research I realized that webinfos are not accessible from users with less privileges. So I had to change my REST API call.This time I had to use /_api/web/Webs

<div ng-controller="subsitesCtrl as vm">
<ul>
	<li ng-repeat="site in vm.sites">
            <a ng-href="{{site.Url}}">{{site.Title}}</a></li>
</ul>
</div>

Be careful that in angular part I changed site.ServerRelativeUrl with site.Url


 function subsitesCtrl($http) {
 var vm = this;

 $http({
 method: 'GET',
 url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/Webs?$select=Title,URL,effectivebasepermissions&$filter=effectivebasepermissions/high%20gt%2032",
 headers: { "Accept": "application/json;odata=verbose" }
 }).success(function (data, status, headers, config) {

 vm.sites = data.d.results;
 }).error(function (data, status, headers, config) {

 alert("error retrieving websites");
 });

 }

As you can see, you have to use effectivebasepermissions to limit the query only to the sites that current user has access. This solution seems to work effectively with all users!

Giorgos Basagiannis

I am a full stack engineer with broad technical skill set. I am passionate about developing high quality software that is scalable and easy to maintain. My main areas of interest include Microsoft Web & Cloud Technologies,JavaScript based frameworks,SharePoint and Office 365.

Leave a Reply

Your email address will not be published. Required fields are marked *