SharePoint Saturday Sydney 2014

November 29, 2014 was a great day for SharePoint Saturday.

I presented "Develop and Build Workflow Apps in SP2013. Wait, Workflow Apps?" - which is a session that covers lots of the new things you can build with SharePoint 2013 workflows using primarily Visual Studio 2013.  These work on premises and in Office 365.

 

The REST end points opens up SharePoint

 

I still think my transition along with exploring new activity and suddenly jumping into REST was tough.  I need to work on how to introduce that point.

The key point stands.  As a developer, or even a power user using Workflows - the REST API opens SharePoint completely to me.  I can use it to create lists, site columns or assign permission groups.  The trouble is that creating the JSON packet to talk to SharePoint end point is quite hard.  Which is why the need (and the ability) to package existing series of Actions into a reusable Custom Activity is a big deal.

 

Confusion over Workflow Custom Activity

 

There was actually a lot of confusion over the artefact "Custom Activity".  In 2010, these were sandbox or coded solutions.  In 2013, Custom Activity is completely declarative.  It is a way for you to save a series of workflow actions into a reusable piece of functionality that you can use over and over.  In my demo project I have about 10 custom activities.

 

Downloads

 

 

News Update

 

We announced at the beginning and the end of SharePoint Saturday 2014 that this would be the last SharePoint Saturday in Australia.  As Microsoft and Industry trends towards Office 365, we will move with that trend.

From 2015 onwards, Office 365 Saturday will return, bigger and with more coverage of Office and SharePoint Online, but also address your On Premises needs.

Hope you have a great holidays and see you soon in 2015!

jQuery Promise syntax to wrap SharePoint SP.SOD

 

jQuery has a special function $.Deferred - which lets you create an Deferred object to build Promise(s).

We use this to simplify everything we do in SharePoint and other JavaScript libraries.

 

Wrapping SP.ClientContext

function GetCurrentUserName() {

var deferred = $.Deferred();
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var currentUser = web.get_currentUser();
ctx.load(currentUser);
ctx.executeQueryAsync( function(sender, args) {
    deferred.resolve();
}, function() {
    deferred.fail();
});

var promise = deferred.promise();
promise.done( function() {
    var title = currentUser.get_title();
});

return promise;
}

Wrapping SP.SOD

function SPLoaded() {

var deferred = $.Deferred();
SP.SOD.executeOrDelayUntilScriptLoaded( function() { deferred.resolve(); }, "sp.js");

return deferred.promise();

}

Resolving multiple promises

var promise1 = ...
var promise2 = ...
var promise3 = ...

$.when(promise1, promise2, promise3).done(function(){

// do something

});

 

Concatenating Arrays of promises

 

var promises = [];
promises.push(promise1);
promises.push(promise2);
...

// use this syntax when you don't know how many promises are there - may be calling REST in a loop.

return $.when.apply($, promises);

 

Combining Array of Promises and SP.SOD

 

function Ready() {

var promises = [];

var deferred1 = $.Deferred();
SP.SOD.executeOrDelayUntilScriptLoaded(deferred1.resolve, "sp.js");
promises.push(deferred1.promise());

var deferred2 = $.Deferred();
SP.SOD.executeOrDelayUntilScriptLoaded(deferred2.resolve, "sp.core.js");
promises.push(deferred2.promise());

 

return $.when.apply($, promises);

}

 

Combining promises

 

$(document).ready(function(){

    var vm = new ViewModel();  // not included in above script
    var promise = vm.Ready();
    promise.done( function() {
        vm.GetCurrentUserName();

    });

});

 

(Updated) And the grand finale

 

function Ready() {

var promises = [];

// using the special javascript argument "arguments"

$.each(arguments, function(index, arg) {
    var deferred = $.Deferred();
    SP.SOD.executeOrDelayUntilScriptLoaded(deferred.resolve, arg);
    promises.push(deferred.promise());
});

return $.when.apply($, promises);

}

 

$(document).ready(function(){

    var vm = new ViewModel();  // not included in above script
    var promise = vm.Ready("sp.js", "sp.core.js");
    promise.done( function() {
        vm.GetCurrentUserName();

    });

});

Using SharePoint Designer 2013 Workflow to copy file via REST on Office 365

This is a bit of trial and error, but works very well at the end, so I want to publish this and share the syntax.

 

Related References:

 

I will tackle the next step.  How do you call a POST REST service, with the CopyTo function on SPFile.  http://msdn.microsoft.com/en-us/library/ms455020.aspx

The flexibility is that you can easily tweak the urls and essentially allow your workflow to copy files anywhere.

 

Step 1.  Understand the correct URL

 

Put this into your browser's address bar (this executes a GET request):

image

No good.  Need POST.

 

Step 2.  Make that SharePoint Designer 2013 Workflow

 

  1. First step, with the POST call, we need to add a Request Header for Accept: application/json; odata=verbose
    Put this in a dictionary variable.

    image
  2. Second step.  Call Web Service!
    image

    You need to set up Request Headers as well.  This has to be done via the Properties, since it's not a link that's shown.  Set this to the dictionary created in the previous step.
    This step is the same as mentioned in Adrian Fiechter's blog.

    image
  3. You should capture the ResponseContent, and add an additional action to log it to History
    The Stage ends.  Go to End of Workflow.

    image

  4. The whole thing, in 3 lines:

    image

Step 3.  Run it.

 

image

Here's me starting the workflow on the top1.png file.

 

image

The top1.png is copied to top2.png!  Interestingly, it's copied the Call Workflow "workflow status" column.  Both links (which is a lookup field) go to the same workflow.

 

image

This is the workflow history. 

Notice that the CopyTo method returned void (null) in this case.  Should there be an error, you'll see it logged here.

 

That's all!  Hope you find these steps useful.