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

brendanlefavreAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ingeborg Hawighorst (Microsoft MVP / EE MVE)Microsoft MVP ExcelCommented:
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
0
brendanlefavreAuthor Commented:
I'm getting an error when I reload the page, and inspect the results via the Google Chrome Developer Tools

Error:
Console Error
File Structure:
File Structure
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

0
Ingeborg Hawighorst (Microsoft MVP / EE MVE)Microsoft MVP ExcelCommented:
Chrome and SharePoint 2010 don't play well together. Before attempting to get anything to work in Chrome, make sure that it works with IE first.

As far as I understand the question, it is about where to best place the Angular library. If the files are loading, and it seems that they are, the file location issue has been resolved and this question has been answered.

You are now following up with a question to troubleshoot your code. That is a different aspect and should go into a new question.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
brendanlefavreAuthor Commented:
original question answered
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft SharePoint

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.