Link to home
Start Free TrialLog in
Avatar of brendanlefavre
brendanlefavreFlag for United States of America

asked on

SharePoint 2010 - Retrieving List Data with AngularJS

I have been searching for an example on how to work with SharePoint 2010 list data, and most references point to SharePoint 2013. I did however find one example on SharePoint.StackExchange.com that shows how a particular users was taking this approach.

I could use some help with setting up the file structure, and how to place this within SharePoint. I believe everything should go into the Style Library, and then add the html to a page, and references to the scripts. Is this the best approach?

Cheers

SharePointListService.js

(function () {
//// SharePointListService.js
"use strict";
var module = angular.module('sharePointList', []);
module.provider('SharePointList', function () {
    var clientCtx;
    var web;
    var configuration = {};
    this.$get = ['$q',"$log", function ($q,$log) {
        var contextLoaded = $q.defer();
        SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
            clientCtx = SP.ClientContext.get_current();
            web = clientCtx.get_web();
            contextLoaded.resolve();
        });
        function createServiceForConfiguration(config) {
            var service = {};
            service.self = service;
            service.clientCtx = clientCtx;
            service.web = web;
            service.getListItems = function (listName, queryString, fields) {
                var deferred = $q.defer();
                contextLoaded.promise.then(function () {
                    var list = web.get_lists().getByTitle(listName);
                    var query = new SP.CamlQuery();
                    query.set_viewXml(queryString);
                    var listItems = list.getItems(query);
                    var fieldList = fields.join(",");
                    clientCtx.load(listItems,"Include("+fieldList+")" );
                    clientCtx.executeQueryAsync(function () {
                        var resultItems = [];
                        var listItemEnumerator = listItems.getEnumerator();
                        while (listItemEnumerator.moveNext()) {
                            var listItem = listItemEnumerator.get_current();
                            var resultItem = {};
                            for (i = 0; i < fields.length; i++) {
                                resultItem[fields[i]] = listItem.get_item(fields[i]);
                            }
                            resultItems.push(resultItem);
                        }
                        deferred.resolve(resultItems);
                    }, function (sender, args) {
                        var messageFormat="Loading of list {0} with  failed with error. {1} \n{2}";
                        var message=messageFormat.format(listName,args.get_message() ,args.get_stackTrace());
                        $log.error(message);
                    })
                });
                return deferred.promise;
            };
            return service;
        }
        return createServiceForConfiguration(configuration);
    }];
}
);})();

Open in new window


app.js

(function () {
"use strict";
var app = angular.module("app1", [
    // angular stuff
    "ui.router",
    "sharePointList",
    "ngGrid",
    'ngSanitize'
]);
app.config(function (SharePointListProvider, $stateProvider, $urlRouterProvider) {
    // For any unmatched url, redirect to /portfolios
    $urlRouterProvider.otherwise("/distributionGroups");
    $stateProvider
     .state('distributionGroups', {
         url: '/distributionGroups',
         templateUrl: 'distributiongroupstemplate.html',
         controller: "SharePointListCtrl"
     });
});
app.controller("SharePointListCtrl", ["$scope", "$state", "SharePointList", "$templateCache", function ($scope, $state, SharePointList, $templateCache) {
    $scope.gridOptions = {
        data: 'distributionGroups',
        enableCellSelection: true,
        enableRowSelection: false,
        enableCellEdit: true,
        columnDefs: [
            { field: 'Title', displayName: 'Title', enableCellEdit: false, width: "160px", resizeable: true },
            { field: 'EMail', displayName: 'E-Mail', width: "160px" }
        ]
    };
    var queryString = "<View><Query><OrderBy><FieldRef Name='Title' Ascending='False'/></OrderBy></Query></View>";
    SharePointList.getListItems("DistributionGroups", queryString,["Title","EMail"]).then(function (distributionGroups) {
        $scope.distributionGroups = distributionGroups;
    });
}]);})();
window.onload = function () {
    var $rootelement = angular.element(window.document);
    var modules = [
        "ng",
        "app1",
        function ($provide) { $provide.value("$rootElement", $rootelement); }
    ];
    var $injector = angular.injector(modules);
    var $compile = $injector.get("$compile");
    var compositeLinkFn = $compile($rootelement);
    var $rootScope = $injector.get("$rootScope");
    compositeLinkFn($rootScope);
    $rootScope.$apply();
}; 

Open in new window


html

<div>
         <a data-ui-sref="distributionGroups">Distribution Groups</a>
   </div>
   <div data-ui-view>default content</div>  
 </div>
<script type="text/ng-template" id="distributiongroupstemplate.html" >
    <div id="distributiongroups">
        <div class="gridStyle" data-ng-grid="gridOptions">
        </div>
    </div>
    </script>

Open in new window

Avatar of Ingeborg Hawighorst (Microsoft MVP / EE MVE)
Ingeborg Hawighorst (Microsoft MVP / EE MVE)
Flag of New Zealand image

Hello,

yes, the Style Library is a good idea for storing script files. Out of the box, the Style Library supports versioning and can be read by all users. You can even check in minor versions of files and see the changes on your machine, while the regular user still sees only the experience with the last published version. So, yes, by all means use the Style Library.

I often create sub folders for Scripts and libraries like jQuery (or Angular), to keep my scripts separate from the downloaded libraries.

If you want the script to work on one page only, then the quickest is to add a Content Editor Web Part and set its "content link" to your script file in the Style Library.

The script file contents could look something like this:

<link rel="stylesheet" type="text/css" href="/sites/path/Style Library/CSS/customCSS.css">
<script type="text/javascript" src="/sites/path/Style Library/jQuery/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/sites/path/Style Library/jQuery/jquery.SPServices-2014.01.min.js"></script>
... load your AngularJS in a similar way

<script type="text/javascript">
 ... your javascript 
</script>
<div>
         <a data-ui-sref="distributionGroups">Distribution Groups</a>
   </div>
   <div data-ui-view>default content</div>  
 </div>
<script type="text/ng-template" id="distributiongroupstemplate.html" >
    <div id="distributiongroups">
        <div class="gridStyle" data-ng-grid="gridOptions">
        </div>
    </div>
    </script>

Open in new window


If you need AngularJS on more than one page, then you can load the JS files in the Master Page instead. If you need details for that, please pipe up.

cheers, teylyn
Avatar of brendanlefavre

ASKER

I'm getting an error when I reload the page, and inspect the results via the Google Chrome Developer Tools

Error:
User generated image
File Structure:
User generated image
The following is added to the home page in a CEWP via the script link to a txt file.

<script type="text/javascript" src="http://portal/sites/angularjs/Style Library/dg/angular.min.js"></script>
<script type="text/javascript" src="http://portal/sites/angularjs/Style Library/dg/jQuery/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="http://portal/sites/angularjs/Style Library/dg/jquery.SPServices-2014.01.js"></script>
<script type="text/javascript" src="http://portal/sites/angularjs/Style Library/dg/SharePointListService.js"></script>
<script type="text/javascript" src="http://portal/sites/angularjs/Style Library/dg/app.js"></script>


<div>
    <a data-ui-sref="distributionGroups">Distribution Groups</a>
   </div>
<div data-ui-view>default content</div>  

<script type="text/ng-template" id="distributiongroupstemplate.html" >
    <div id="distributiongroups">
        <div class="gridStyle" data-ng-grid="gridOptions"></div>
    </div>
</script>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Ingeborg Hawighorst (Microsoft MVP / EE MVE)
Ingeborg Hawighorst (Microsoft MVP / EE MVE)
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
original question answered