4

I have one requirement to start the SP workflow through JavaScript. For this, I have wrote some lines of code to start the workflow. But I am getting a Subscription failed error due to undefined object. This is occurring at ExcecuteasyncQuery method. So I didn't get which object returns the undefined value. My code is shown below.

<script type="text/javascript" src="/_layouts/15/sp.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.core.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.workflowservices.js">          </script>
<script type="text/javascript">
var subID = "3debdbad-db52-4586-87e1-40e4db581da5";

function GetCurrentItemID()
{
var ctx = SP.ClientContext.get_current();
var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);

for (item in selectedItems)
{
var itemId = selectedItems[item].id;
startWorkflow(itemId, subID);
}
}

function startWorkflow(itemID, subID) {    
var context = SP.ClientContext.get_current();
var web = context.get_web();
var wfServiceManager =    SP.WorkflowServices.WorkflowServicesManager.newObject(context, web);
var subscription = wfServiceManager.getWorkflowSubscriptionService().getSubscription(subID);

context.load(subscription);

context.executeQueryAsync(
function(sender, args){
    alert("Subscription load success. Attempting to start workflow.");        
    var inputParameters = {};
    wfServiceManager.getWorkflowInstanceService().startWorkflowOnListItem
    (subscription, itemID, inputParameters);

    context.executeQueryAsync(
        function(sender, args){ alert("Successfully starting workflow."); },
        function(sender, args){ 
            alert("Failed to start workflow.");
            alert("Error: " + args.get_message() + "\n" + args.get_stackTrace());
        }
       );
       },
function(sender,args){
    alert("Failed to load subscription.");
    alert("Error: " + args.get_message() + "\n" + args.get_stackTrace());
}
 );
  }
 </script>

I am calling the GetCurrentItemID() function at the button click. But at that time, I am getting the following error.

Failed to load subscription

Invalid Request

Undefined

Could any one please help me to sort out this issue. Thanks in advance.

1

1 Answer 1

0

I've used this a bunch and it works well. Let me know if it works for you as well. The most up to date code will be hosted on Github, but I'm copying it below for posterity.

https://gist.github.com/iOnline247/1b3c26f7175296a44274

/*!
 * Created by Matthew Bramer
 * Released under the MIT license
 * Date: 2015-04-18
 * Props to: http://plumsail.com/blog/2015/02/start-sharepoint-2013-workflows-selected-items/
 * Tested using SharePoint Online.
 * On-Prem still needs testing.
 */

window.$sp = window.$sp || {};
window.$sp.wf = (function( $, undefined ) {
    "use strict";
    var ctx,
        web,
        wfManager,
        JS_SUFFIX = ".js",
        SP_WORKFLOW_SERVICES = "SP.WorkflowServices",
        SP_WORKFLOW_SERVICES_SCRIPT_NAME = SP_WORKFLOW_SERVICES + JS_SUFFIX,
        risGuid = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i,
        oDataHeader = "application/json;odata=verbose",
        initializeVariables = function() {
            ctx = SP.ClientContext.get_current();
            web = ctx.get_web();
            wfManager = SP.WorkflowServices.WorkflowServicesManager.newObject( ctx, web );
        },
        registerWFscripts = function() {
            SP.SOD.registerSod(
                SP_WORKFLOW_SERVICES_SCRIPT_NAME,
                SP.Utilities.Utility.getLayoutsPageUrl( SP_WORKFLOW_SERVICES + JS_SUFFIX )
            );
            SP.SOD.executeFunc(
                SP_WORKFLOW_SERVICES_SCRIPT_NAME,
                SP_WORKFLOW_SERVICES + ".WorkflowServicesManager",
                initializeVariables
            );
        },
        init = function() {
            SP.SOD.executeFunc(
                "sp" + JS_SUFFIX,
                "SP.ClientContext",
                registerWFscripts
            );
        },
        set_errorHandler = function( func ) {
            errorHandler = func;
        },
        errorHandler = function( sender, args ) {
            var message = this,
                spError = args && args.get_message,
                restAPIError = sender && sender.responseText

            ;

            if( this.id ) {
                message += " on item with ID: " + this.id;
            }

            SP.UI.Notify.addNotification( message, false );
            console.log( message );

            if( spError ) {
                console.log( "Error:", args.get_message(), "\nStackTrace:", args.get_stackTrace() );
            }

            if( restAPIError ) {
                console.log( restAPIError );
            }
        },
        set_successHandler = function( func ) {
            successHandler = func;
        },
        successHandler = function( sender, args ) {
            var wfName = this.name || this.subscription && this.subscription.get_name(),
                message = "Workflow " + wfName + " has started."

            ;

            if( this.id ) {
                message = message.replace(".", "");
                message += " on this item. ID: " + this.id;
            }

            SP.UI.Notify.addNotification( message, false );
        },
        fireWfByName = function( sender, args ) {
            var subscription = this.subscription,
                id = this.id,
                initiationParams = this.initiationParams || {},
                workflows = subscription.getEnumerator(),
                workflow,
                foundWrkFlow = false

            ;

            while( workflows.moveNext() ) {
                workflow = workflows.get_current();

                if( workflow.get_name() === this.name ) {
                    startWorkflow({
                        subscriptionId: workflow.get_id(),
                        id: id,
                        initiationParams: initiationParams
                    });

                    foundWrkFlow = true;
                    break;
                }
            }

            if( !foundWrkFlow ) {
                errorHandler.call( "Could not find workflow named: " + this.name );
            }
        },
        fireWfBySubscription = function( sender, args ) {
            var subscription = this.subscription,
                id = this.id,
                initiationParams = this.initiationParams || {},
                wfInstance = wfManager.getWorkflowInstanceService()

            ;

            // https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.workflowinstanceservice_methods.aspx

            if( id ) {
                wfInstance.startWorkflowOnListItem( subscription, id, initiationParams );
            } else {
                wfInstance.startWorkflow( subscription, initiationParams );
            }

            ctx.executeQueryAsync(
                successHandler.bind( this ),
                errorHandler.bind( "Could not fire workflow. SubscriptionId: " + this.subscriptionId )
            );
        },
        startWorkflow = function( opt ) {
            var subscriptionService = wfManager.getWorkflowSubscriptionService(),
                success,
                error

            ;

            // different methods to fire workflows with 2013.
            // https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.workflowservices.workflowsubscriptionservice_members.aspx
            if( opt.subscriptionId ) {
                opt.subscription = subscriptionService.getSubscription( opt.subscriptionId );
                ctx.load( opt.subscription );
                success = fireWfBySubscription.bind( opt );
                error = errorHandler.bind( "Failed to load subscription: " + opt.subscriptionId );
            } else {
                opt.subscription = subscriptionService.enumerateSubscriptions();
                ctx.load( opt.subscription );
                success = fireWfByName.bind( opt );
                error = errorHandler.bind( "Failed to load workflow subscriptions." );
            }

            ctx.executeQueryAsync(
                success,
                error
            );
        },
        removeDemCurlies = function( v ) {
            return v.replace( /{|}/g, "" );
        },
        getListItemDeets = function( listUrl ) {
            return $.ajax({
                type: "GET",
                url: listUrl,
                dataType: "json",
                headers: {
                    "Accept": oDataHeader,
                    "Content-Type": oDataHeader
                }
            });
        },
        fire2010Workflow = function( data ) {
            var success,
                listGuid = data.d.__metadata.uri.match( risGuid )[ 0 ],
                itemId = data.d.GUID
            ;

            this.result = this.subscriptionService.startWorkflow( this.name, null, listGuid, itemId, this.initiationParams );
            success = successHandler.bind( this );

            ctx.executeQueryAsync(
                success,
                this.error
            );
        },
        start2010Workflow = function( opt ) {
            var subscriptionService = wfManager.getWorkflowInteropService(),
                wfName = opt.name,
                id = opt.id,
                itemGuid,
                initiationParams = opt.initiationParams,
                queryPrefix = "/_api/web/lists",
                querySuffix = "/items(" + id + ")?$select=GUID",
                // May need to do this later when ctx is dynamic.
                // listUrl = web.get_url(),
                listUrl = _spPageContextInfo.webAbsoluteUrl + queryPrefix,
                listGuid,
                errorMessage = "Failed to fire 2010 {0} Workflow.",
                success,
                error

            ;

            // Fire 2010 workflows!
            // https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.interopservice.startworkflow.aspx

            // Not sure if opt.result is going to be helpful, but leaving it here for the meantime.
            // If it is useful, then I'll bind it to the both handlers.
            // If not, I'll drop it altogether.
            if( id ) {
                listGuid = opt.list.match( risGuid );
                if( listGuid ) {
                    listGuid = removeDemCurlies( listGuid[ 0 ] );
                    listUrl += "(guid'" + listGuid + "')";
                } else {
                    listUrl += "/GetByTitle('" + opt.list + "')";
                }

                listUrl += querySuffix;

                // converts numbers to strings.
                id = id + "";
                itemGuid = id.match( risGuid );

                if( listGuid && itemGuid ) {
                    // List GUID and item GUID were provided, no need for API call.
                    opt.result = subscriptionService.startWorkflow( wfName, null, listGuid, itemGuid[ 0 ], initiationParams );
                    success = successHandler.bind( opt );
                    error = errorHandler.bind( errorMessage.replace("{0}", "Site") );
                } else {
                    // Need to resolve List GUID and get the item GUID.
                    opt.subscriptionService = subscriptionService;
                    opt.error = errorHandler.bind( errorMessage.replace("{0}", "List") );

                    return getListItemDeets.bind( opt )( listUrl )
                        .then( fire2010Workflow.bind( opt ), opt.error );
                }
            } else {
                // Site WF
                opt.result = subscriptionService.startWorkflow( wfName, null, null, null, initiationParams );
                success = successHandler.bind( opt );
                error = errorHandler.bind( errorMessage.replace("{0}", "Site") );
            }

            ctx.executeQueryAsync(
                success,
                error
            );
        }

    ;


    init();

    // TODO:
    // On-Prem testing.
    // Look at custom events.
    // https://msdn.microsoft.com/en-us/library/office/dn481315.aspx
    // Add promises.
    return {
        set_errorHandler: set_errorHandler,
        set_successHandler: set_successHandler,
        startWorkflow: startWorkflow,
        start2010Workflow: start2010Workflow
    };
}( window.jQuery ));


/*
 * Usage
 * via subscriptionId or Workflow Name. Preferably the latter.
*/

// List bound WF fired by Workflow Name, Muy bien!
$sp.wf.startWorkflow({
    name: "Send Email",
    id: 1,
    initiationParams: {
        EasyText: "What's up?",
        // `Here I Am` is the real initation parameter name. Note the spaces.
        HereIam: "<p><b>heyo!</b></p><p>otra ves</p>"
    }
});

// Site workflows! YaY!
$sp.wf.startWorkflow({
    name: "Site WF",
    initiationParams: {
        WooP: "<b>That's what's up!</b>"
    }
});

// 2010 Site WF!
$sp.wf.start2010Workflow({
    name: "Site WF - 2010",
    initiationParams: {
        // `Something with Spaces` is the real initation parameter name. Note the spaces and casing.
        SomethingwithSpaces: "<b>That's what's up!</b>"
    }
});

// 2010 List Bound WF.
$sp.wf.start2010Workflow({
    name: "SendEmail2010",
    list: "Test",
    id: 1,
    initiationParams: {
        "ThingsChangePeopleChange": "<b>Used list display name and item id.</b>"
    }
});

$sp.wf.start2010Workflow({
    name: "SendEmail2010",
    list: "{FD21AC5B-15D9-443A-B7A5-1FB6A2AF667D}",
    id: 1,
    initiationParams: {
        "ThingsChangePeopleChange": "<b>Used list GUID and item id.</b>"
    }
});

$sp.wf.start2010Workflow({
    name: "SendEmail2010",
    list: "{FD21AC5B-15D9-443A-B7A5-1FB6A2AF667D}",
    id: "{211ffdfc-69c5-4206-917d-befe62a6ffb4}",
    initiationParams: {
        "ThingsChangePeopleChange": "<b>Used list GUID and item GUID. Prevents a call to SP's REST API.</b>"
    }
});

// The ugly duckling...  Don't use this, please. :)
// Via Subscription ID, YUCK!
$sp.wf.startWorkflow({
    subscriptionId: "{CE3890BC-3361-4F1C-9036-40A07E0EC449}",
    id: 1
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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