1

I am creating a SharePoint Hosted App and the default Visual Studio project uses jQuery to access the SP.clientContext to get_currentUser and save it in a global variable.

To trigger an AngularJS app, I want to pass that global variable to the $scope. Here's my app.js:

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var myApp = angular.module('myApp', []);

function TodoCtrl($scope, $SharePointJSOMService) {
    $scope.user = user;
    console.dir($scope);
    $scope.current_user = user.$2_0.$K_0.Email;
    console.dir($scope);
}

in the console, the first console.dir shows the value. Here is the output:

object Object {
   [functions]: ,
   $$asyncQueue: [ ],
   $$childHead: null,
   $$childTail: null,
   $$destroyed: false,
   $$isolateBindings: { },
   $$listeners: { },
   $$nextSibling: null,
   $$phase: "$apply",
   $$prevSibling: null,
   $$watchers: null,
   $id: "003",
   $parent: { },
   $root: { },
   this: { },
   user: {
      [functions]: ,
      $0_0: { },
      $2_0: {
         [functions]: ,
         $1E_0: null,
         $1f_0: null,
         $1t_0: null,
         $1Y_0: null,
         $12_0: false,
         $c_0: null,
         $D_0: null,
         $K_0: {
            [functions]: ,
            Email: "me@mydomain.onmicrosoft.com",
            Id: 9,
            IsHiddenInUI: false,
            IsSiteAdmin: false,
            LoginName: "i:0#.f|membership|me@corporate.com",
            PrincipalType: 1,
            Title: "MyLast, MyFirst",
            UserId: { }
         },
         $O_0: null,
         $Z_0: { }
      },
      $2K_0: false,
      $U_0: null
   }
}

But the console.dir of $scope.current_user = user.$2_0.$K_0.Email; produces the error of "Unable to get property 'Email' of undefined or null reference" How can $K_0 be null there where it is a full object 2 rows of code above???

Thanks in advance!

UPDATE-- Here's my $SharePointJSOMService code:

myApp.service('SharePointJSOMService', function ($q, $http) {
    this.getCurrentUser = function () {
        var deferred = $.Deferred();
        //First we must call the EnsureSetup method
        JSRequest.EnsureSetup();
        hostweburl = decodeURIComponent(JSRequest.QueryString["SPHostUrl"]);
        appweburl = decodeURIComponent(JSRequest.QueryString["SPAppWebUrl"]);

        var userid = _spPageContextInfo.userId;
        var restQueryUrl = appweburl + "/_api/web/getuserbyid(" + userid + ")";

        var executor = new SP.RequestExecutor(appweburl);
        executor.executeAsync({
            url: restQueryUrl,
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: function (data, textStatus, xhr) {
                deferred.resolve(JSON.parse(data.body));
            },
            error: function (xhr, textStatus, errorThrown) {
                deferred.reject(JSON.stringify(xhr));
            }
        });
        return deferred;
    };

    this.getTasksREST = function ($scope, listTitle) {
        var deferred = $.Deferred();
        //First we must call the EnsureSetup method
        JSRequest.EnsureSetup();
        hostweburl = decodeURIComponent(JSRequest.QueryString["SPHostUrl"]);
        appweburl = decodeURIComponent(JSRequest.QueryString["SPAppWebUrl"]);

        var restQueryUrl = appweburl + "/_api/SP.AppContextSite(@target)/web/lists/getByTitle('" + listTitle + "')/items?$select=Title,ID,DueDate,Status,Priority,AssignedTo/ID,AssignedTo/Title,AssignedTo/Name&$expand=AssignedTo/ID,AssignedTo/Title,AssignedTo/Name&@target='" + hostweburl + "'";

        var executor = new SP.RequestExecutor(appweburl);
        executor.executeAsync({
            url: restQueryUrl,
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: function (data, textStatus, xhr) {
                deferred.resolve(JSON.parse(data.body));
            },
            error: function (xhr, textStatus, errorThrown) {
                deferred.reject(JSON.stringify(xhr));
            }
        });
        return deferred;
    };

    this.checkTaskList = function ($scope, listTitle) {
        var deferred = $.Deferred();
        //First we must call the EnsureSetup method
        JSRequest.EnsureSetup();
        hostweburl = decodeURIComponent(JSRequest.QueryString["SPHostUrl"]);
        appweburl = decodeURIComponent(JSRequest.QueryString["SPAppWebUrl"]);

        var context = new SP.ClientContext(appweburl);
        var appContextSite = new SP.AppContextSite(context, hostweburl);
        var web = appContextSite.get_web();
        context.load(web);

        //check list exists
        var lists = web.get_lists();
        context.load(lists);
        context.executeQueryAsync(
            function () {
                var isListAvail = false;
                var listEnumerator = lists.getEnumerator();
                while (listEnumerator.moveNext()) {
                    list = listEnumerator.get_current();
                    if (list.get_title() == listTitle) {
                        isListAvail = true;
                    }
                }
                if (isListAvail != true) {
                    //create the list
                    var listCreationInfo = new SP.ListCreationInformation();
                    listCreationInfo.set_title(listTitle);
                    listCreationInfo.set_templateType(SP.ListTemplateType.tasks);
                    var list = web.get_lists().add(listCreationInfo);
                    context.load(list);
                    context.executeQueryAsync(
                        function () {

                        },
                        function (sender, args) {
                            deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
                        }
                    );
                }
            },
            function (sender, args) {
                deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
            }
        );

        return deferred.promise;
    };

    this.saveTask = function (scope, listTitle) {
        var deferred = $.Deferred();

        var context = new SP.ClientContext(appweburl);
        var appContextSite = new SP.AppContextSite(context, hostweburl);
        var web = appContextSite.get_web();
        context.load(web);
        var list = web.get_lists().getByTitle('Tasks');


        var listItem = list.getItemById(scope.todo.id);
        listItem.set_item('Title', scope.todo.text);
        var status = 'Not started';
        if (scope.todo.done === true)
            status = 'Completed';
        listItem.set_item('Status', status);
        listItem.set_item('DueDate', scope.todo.dueDate);

        var user = getUserInfo(scope.todo.id);
        if (user['Description'] != null)//if the people picker isn't changed, then no need to update (Description only populated if user selected in picker)
        {
            var users = new Array();
            users.push(SP.FieldUserValue.fromUser(user['Description']));
            scope.todo.assignedTo = user['DisplayText'];
            scope.todo.assignedToName = user['Description'];
            listItem.set_item('AssignedTo', users);
        }
        listItem.update();

        context.executeQueryAsync(
            Function.createDelegate(this, function (sender, args) {
            }),
            Function.createDelegate(this, function (sender, args) {
                deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
            })
        );
        return deferred.promise;
    }

    this.bumpTask = function (scope, listTitle){
        var deferred = $.Deferred();

        var context = new SP.ClientContext(appweburl);
        var appContextSite = new SP.AppContextSite(context, hostweburl);
        var web = appContextSite.get_web();
        context.load(web);
        var list = web.get_lists().getByTitle('Tasks');

        var listItem = list.getItemById(scope.todo.id);
        listItem.set_item('DueDate', scope.todo.dueDate);
        listItem.update();

        context.executeQueryAsync(
            Function.createDelegate(this, function (sender, args) {
            }),
            Function.createDelegate(this, function (sender, args) {
                deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
            })
        );
        return deferred.promise;
    }

    this.deleteTask = function (scope, listTitle) {
        var deferred = $.Deferred();

        var context = new SP.ClientContext(appweburl);
        var appContextSite = new SP.AppContextSite(context, hostweburl);
        var web = appContextSite.get_web();
        context.load(web);
        var list = web.get_lists().getByTitle('Tasks');

        var listItem = list.getItemById(scope.todo.id);
        listItem.deleteObject();
        context.executeQueryAsync(
                Function.createDelegate(this, function () {
                }),
                Function.createDelegate(this, function () {
                    deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
                })
            );
        return deferred.promise;
    }

    this.addTask = function (listTitle, title, dueDate) {
        var deferred = $.Deferred();

        var context = new SP.ClientContext(appweburl);
        var appContextSite = new SP.AppContextSite(context, hostweburl);
        var web = appContextSite.get_web();
        context.load(web);
        var list = web.get_lists().getByTitle(listTitle);

        // create the ListItemInformational object
        var listItemInfo = new SP.ListItemCreationInformation();
        var listItem = list.addItem(listItemInfo);
        listItem.set_item('Title', title);
        listItem.set_item('DueDate', dueDate)
        var users = new Array();
        users.push(SP.FieldUserValue.fromUser(currentUser.LoginName.split("|")[1]));
        listItem.set_item('AssignedTo', users)
        listItem.update();

        context.executeQueryAsync(
            function () {
                var id = listItem.get_id();
                deferred.resolve(id);
            },
            function (sender, args) {
                deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
            }
        );

        return deferred;
    };
});


// Render and initialize the client-side People Picker.
function initializePeoplePicker(peoplePickerElementId, displayName, userName) {

    // Create a schema to store picker properties, and set the properties.
    var schema = {};
    schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
    schema['SearchPrincipalSource'] = 15;
    schema['ResolvePrincipalSource'] = 15;
    schema['AllowMultipleValues'] = false;
    schema['MaximumEntitySuggestions'] = 50;
    schema['Width'] = '280px';
    var users = null;

    if (displayName != null) {
        users = new Array(1);
        var user = new Object();
        user.AutoFillDisplayText = displayName;
        user.AutoFillKey = userName;
        user.AutoFillSubDisplayText = "";
        user.DisplayText = displayName;
        user.EntityType = "User";
        user.IsResolved = true;
        user.Key = userName;
        user.ProviderDisplayName = "Tenant";
        user.ProviderName = "Tenant";
        user.Resolved = true;
        users[0] = user;
    }
    // Render and initialize the picker. 
    // Pass the ID of the DOM element that contains the picker, an array of initial
    // PickerEntity objects to set the picker value, and a schema that defines
    // picker properties.
    SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementId, users, schema);
}

// Query the picker for user information.
function getUserInfo(id) {
    var fieldName = 'peoplePickerDiv' + id + '_TopSpan';

    var peoplePickerDiv = $("[id$='" + fieldName + "']");

    // Get the people picker object from the page.
    var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDiv[0].id];


    // Get information about all users.
    var users = peoplePicker.GetAllUserInfo();
    return users[0];
}
2

Have you tried loading the user first? Like this:

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
// Load user here:
context.load(user);
var myApp = angular.module('myApp', []);

function TodoCtrl($scope, $SharePointJSOMService) {
  // I'm not familiar with the provider $SharePointJSOMService
  // I found an example online where I can see in the source that it might call ".executeQueryAsync",
  // so you don't have to. But I will include it to be sure

  context.executeQueryAsync(function() {
    $scope.user = user;
  });
}

Also, what provider is SharePointJSOMService?

  • Just found other examples where $SharePointJSOMService is a service using REST, which is not related to your code, so not sure what to make of it – eirikb Apr 30 '14 at 5:31
  • $SharePointJSOMService is a custom service. I am using the base code from Andrew Connell's new SharePoint SPA Apps's course on PluralSight (a really good course, by the way). If it helps, I added the code of that service in a question update. – jgravois Apr 30 '14 at 9:54
  • I am also using some code from Jeremy Thake's presentation at a 2013 Convention on using AngularJS for SharePoint SPA Apps. I think that service is actually from Jeremy Thake. – jgravois Apr 30 '14 at 10:01
  • I will have to wait to get to work to try loading the user first since I don't have access to the code here. Are you thinking that it's a timing issue? But how can something be defined and visible and then null 2 lines later?? – jgravois Apr 30 '14 at 10:03
  • @erikb, you were absolutely correct. Loading the user in the global namespace and harvesting it with executeQueryAsync in the controller did the trick. – jgravois Apr 30 '14 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.