Link to home
Start Free TrialLog in
Avatar of Howard Bash
Howard BashFlag for United States of America

asked on

SharePoint and Chaining Promises On CSOM List operations

Setting up some asyn calls with Promises.  I am trying to get a handle on how to chain some async calls using Promises.
Let me describe the scenario by async functions.  I'll "code" them inline with comments.

GetAllFields (uses CSOM to get back some data from a SharePoint List)
  On Return, I will have a JSON arrary of Fields= [{'Title', some text, 'Anther Field': some more text}, ...]

CheckIfAlreadyUsedThisItem(ID from GetAllFields)
  On Return, I will have a true or false and know if I will either put up an alert saying already processed, or continue to the next call

SaveRelatedDataIfNotDoneAlready(JSON arrary of Fields) populates another list.

Just not too clear on how to set this up.  Further, I would like to wrap it all in a namespace...
MySpace = {
}


And execute this promise chain via some call such as Myspace.SomePromie();
Avatar of leakim971
leakim971
Flag of Guadeloupe image

MySpace.GetAllFields = new Promise(function(resolve, reject) {
    // uses CSOM to get back some data from a SharePoint List
    resolve(data);
}).then(function(JSON_Arrary_Of_Fields) {
     var arr = new Array();
     // loop over JSON_Arrary_Of_Fields
     return arr; // arr like [{'Title', some text, 'Anther Field': some more text}, ...];
}).then(function(JSON_Arrary_Of_Fields) {
     new Promise(function(resolve, reject) {
              // CheckIfAlreadyUsedThisItem
              // ID from GetAllFields
              resolve(bUsed); // bUsed is true or false "On Return, I will have a true or false"
     }).then(function(bResult) {
            if(bResult)
                alert("already processed"); // and know if I will either put up an alert saying "already processed", or continue to the next call
            else
                SaveRelatedDataIfNotDoneAlready(JSON_Arrary_Of_Fields); // populates another list.
     });
});

Open in new window

Avatar of Howard Bash

ASKER

Given that this is close to the CSOM call to get back some list data:

DoSharePointAsyncCall: function DoSharePointAsyncCall(itemId) {
		try {

			MySpace.CurrentDealID = itemId;

			var clientContext = SP.ClientContext.get_current();
			var currentList = clientContext.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList());
			MySpace.singleItem = currentList.getItemById(itemId);

			clientContext.load(MySpace.singleItem, 'ID', 'Title', 'Abstract', 'DateOfDelivery', 'Team');
			clientContext.executeQueryAsync(Function.createDelegate(this, MySpace.TTPOnSucceeded), Function.createDelegate(this, MySpace.TTPOnFailed));
			
		} catch(err) {
			console.log(err.message);						
		}
	},
	
TTPOnSucceeded: function TTPOnSucceeded() {
  var sID = "";		
  var sTitle = "";
  var sAbstract = "";
  var sDateOfDelivery = "";
  var sTeam = "";
	
  sID = MySpace.singleItem.get_item('ID');
  sTitle = MySpace.singleItem.get_item('Title');
  sAbstract = MySpace.singleItem.get_item('Abstract');
  sDateOfDelivery = MySpace.singleItem.get_item('DateOfDelivery');
  sTeam = MySpace.singleItem.get_item('Team');

  var TeamArray = [];
  if (sTeam != null) {
	if (sTeam.length>0) {
		for (var cnt=0; cnt<sTeam.length; cnt++) {
		  TeamArray.push(sTeam[cnt]);
		}
	}  
  }

  var Item = {ID: sID, Title: sTitle, Abstract: sAbstract, DateOfDelivery: sDateOfDelivery, Team: TeamArray};		
  MySpace.AllMyFields.push(Item);

},

TTPOnFailed: function TTPOnFailed() {
	console.log('Error occurred: ' + args.get_message());		
}

Open in new window



How do you morph this into the above promise framework?
do you really need promise ?
why not using MySpace.TTPOnSucceeded especialy because you're using MySpace.singleItem or again TeamArray  ?
Two of three functions are async.  I can handle it chaining the delegates. But, wanted to delve into promises and see if they would streamline the process.
ASKER CERTIFIED SOLUTION
Avatar of leakim971
leakim971
Flag of Guadeloupe 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
Can you explain how to use the reject()  in this setup?  I tried to modify the code adding a section for fail. But, didn't make it all the way their.  The following is my minor update with a place (I think for the missing).

var MySpace = {
    IsTrue: false,

    test : function() {
        this.DoSharePointAsyncCall(3000).then(function(result) {
            alert("we're in test\nthe message is:"+result);
        });
    },
    DoSharePointAsyncCall: function DoSharePointAsyncPromise(itemId) {
        if (MySpace.IsTrue) {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    alert("we're in DoSharePointAsyncPromise");
                    var message = "we used " + itemId + "ms for the timer";
                    PROMOTION.TTPOnSucceeded(message, resolve);
                }, itemId);
            });
        }
        else {
            //???
            });
        }
    }
}

Open in new window

Can you explain how to use the reject()  in this setup?

The reject is not used (no fail in a setTimeout)
The setTimeout is just to show an asynchronous function

What about :

        DoSharePointAsyncCall: function DoSharePointAsyncCall(itemId) {
            return new Promise(function(resolve, reject) {
                try {
                    MySpace.CurrentDealID = itemId;

                    var clientContext = SP.ClientContext.get_current();
                    var currentList = clientContext.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList());
                    MySpace.singleItem = currentList.getItemById(itemId);

                    clientContext.load(MySpace.singleItem, 'ID', 'Title', 'Abstract', 'DateOfDelivery', 'Team');
                    clientContext.executeQueryAsync(Function.createDelegate(this, MySpace.TTPOnSucceeded), Function.createDelegate(this, MySpace.TTPOnFailed));
                } catch(err) {
                    console.log(err.message);
                    reject(err.message);
                }
            });
        },

        TTPOnSucceeded: function TTPOnSucceeded() {
            var sID = "";
            var sTitle = "";
            var sAbstract = "";
            var sDateOfDelivery = "";
            var sTeam = "";

            sID = MySpace.singleItem.get_item('ID');
            sTitle = MySpace.singleItem.get_item('Title');
            sAbstract = MySpace.singleItem.get_item('Abstract');
            sDateOfDelivery = MySpace.singleItem.get_item('DateOfDelivery');
            sTeam = MySpace.singleItem.get_item('Team');

            var TeamArray = [];
            if (sTeam != null) {
                if (sTeam.length>0) {
                    for (var cnt=0; cnt<sTeam.length; cnt++) {
                        TeamArray.push(sTeam[cnt]);
                    }
                }
            }

            var Item = {ID: sID, Title: sTitle, Abstract: sAbstract, DateOfDelivery: sDateOfDelivery, Team: TeamArray};
            MySpace.AllMyFields.push(Item);
            this.resolve(something); // not sure what you want to send to the ".then(function(something) {

        },

        TTPOnFailed: function TTPOnFailed() {
            console.log('Error occurred: ' + args.get_message());
            this.reject(someerror)
        }

Open in new window

Let me describe the scenario completely:

I select a list item and click a button

  • I get the ID of the list item and make first async call to get all that items column values
  • I call second async function using the select List Item ID to determine if that ID is saved (foreign key like) on second list and return true or false.
  • If I return false (the foreign key value wasn't found in second list, I create the new list item and add the values from the first async call as the column values for this new list item
  • Else Popup alert that the item already exists in second list.
// I get the ID of the list item and
var id = someid;
// make first async call to get all that items column values
DoSharePointAsyncCall(id).then(function(I_dont_know_what) {
         // At this point we already called TTPOnSucceeded and it return I don't know what (check my comment line 43)

         // I call second async function using the select List Item ID to determine if that ID is saved (foreign key like)
         // on second list and return true or false.
         
});