Nintex Workflow is a highly used product with SharePoint (2010, 2013, on-prem and online). It is a process automation application that allows users to quickly design and publish workflows. It is easy to use and leverages a simple to use drag-and-drop browser based interface.
At Softlanding we regularly meet clients who need help maximizing their Nintex investments by creating new workflows or modifying existing ones. Recently we created a multi-stage vacation request approval workflow for a large client that will be used by hundreds of users spread across multiple offices.
From this and other experiences, here are some tips for non-programmers who are just starting to develop their first few Nintex workflows.
Planning Is Everything
When planning workflows, it is crucial to understand what the current manual process is and how the end goal looks like. In your meetings with users discuss and record different user scenarios in detail. For example, when a vacation request is approved, who should be notified? If the request is rejected, what series of actions will happen? If the workflow has errors, who needs to be alerted? From these scenarios quickly create a flow chart on paper and draft your test scripts. Then, actively engage with people familiar with the current process and let them constantly review your plans and designs.
You can quickly prototype and review business processes using Nintex as-is. Simply add and organize actions in a workflow without actually configuring any details. This quickly gives you and your users a sense of what Nintex can do and how the current business process can be mapped to an automated workflow.
The Unspoken Workflow
Planning item permissions is an important albeit less talked about topic. Remember to set aside time to discuss roles and permissions with your users, and to ask questions such as who should see what content, how permissions changes over time, and what existing policies need to be respected.
Think about setting up "superuser" SharePoint groups where users in the group have more control over editing/deleting items involved in a workflow. For example, users submitting leave request items should only be able to view/edit/delete their own requests, while users in a "HR Members" group can see all requests, but cannot delete any of them. Then, you could have an "Admin Members" group that can edit and delete any items at any time. As an item transitions from one stage to the next, the permissions for it are likely changing as well.
Changing the item's permissions as the workflow progresses can be imagined as a separate yet embedded workflow.
What Could Go Wrong?
Getting a workflow to reach a successful end state may look deceptively simple at first glance. For example, getting a user's information from AD, having multiple user approve a few tasks, and doing lookups/inserts to other lists is easy to set up quickly. Your workflows may look ready to get deployed, but remember that the real world is messy and hard to predict! Users can enter strange or invalid inputs, lists can get deleted, items can get moved, and other systems can go unresponsive.
Therefore, be proactive about handling situations where your workflow may fail. What if an invalid input was entered, some information is missing in AD, or a lookup list doesn't exist? What happens when a switch action is not able to filter on a value that has a typo? What happens when a REST message returns HTTPStatus = 206? What was the variable/conditional that caused the workflow to fail? You may be spending more time than you initially thought handling these various "failed" scenarios.
Workflows, when done right, need to be complete, robust, verbose, and entirely predictable.
Here are a few tips to plan for failure and speed up debugging:
- Fresh set of eyes - Recruit someone who is new to your workflow and let them try to break your workflow or enter invalid states.
- Make your workflow "talkative" - When variables are dynamically updated by an action, immediately log its value into the workflow history list. This will greatly help with tracking down and fixing issues later. Keep updating the history list with non-technical messages as you transition through your workflow.
- Be defensive - When data is collected from a user or from an external system, use "Set a condition" statements immediately after to check that the incoming data is valid.
- Similarly, when querying data in a different list or site, check and plan for scenarios where the query returns nothing.
- When using web requests, check that the response HTTPStatus value is as expected, and that data is returned in the XML.
- In Switch conditionals, remember to turn on the "Other" branch to handle scenarios when no cases are matched. This option is turned off by default!
Reuse and Recycle
In a workflow that has approval or decision making tasks you will frequently have rejection scenarios where the workflow ends in an unsuccessful state. In this state, a field like "Status" may be set to "Rejected", emails may be sent to the workflow initiator and/or SharePoint group(s), and other changes may be made to reflect this failed state. You may also have similar scenarios where something is approved at one or many levels, and a series of repeatable actions need to be kicked off at each level as well.
To be more efficient when developing workflows, try to spot these frequently repeating actions early on and save them in reusable workflow snippets using the "Action set > Save as Snippet" functionality. These reusable snippets can then be inserted into various places throughout your workflows.
Here are some snippets that you should identify, create, refine, and save early on in your project:
- A request is rejected snippet - Emails users, sets field values, writes to the history log
- A request is approved snippet - Attach a file, write to a different list, and kick off a different workflow
- A workflow has errored snippet - Write to the history log, email a SharePoint group with IT users, and reverse any previous actions
Alternatively, you can also consider using the "State machine" action where you have different states handling different terminal (i.e. final or "wrap up") scenarios. In some situations, this is the better way to go if you have repeatable terminal actions.
The number of variables in workflows quickly grows as you develop workflows with greater complexity. In one completed workflow we designed, we had almost 50 variables created in total to store numbers, users, collections, multiple lines of text, and other information.
It is easy to see how the number of variables quickly grows. Imagine that you need to get some user's first names from AD, and do some operations on them. You will first need to create a collection variable to store the returned value from a Query AD action. Then, using the "Collection operation" action, you may want to count, pop, or perform a "For Each" action on the collection to output pieces of data into integer, string, or boolean variables. Finally, you may need to do some string building, arithmetic calculations, and comparisions which again outputs to new variables.
In summary, the process of getting, transforming, and updating data involves many inputs/outputs that will need storage in a quickly growing list of variables.
To keep your variable names organized and sane, decide on a naming convention and stick with it. For example, try naming your variables descriptively with this format which allows you to quickly see what type a variable is:
Here are a few actual variable names that we have used:
Also, if you have variables that remain constant in the whole workflow, capitalize it like this:
Depending on what kind of workflow you are designing, you can also consider using other naming conventions like:
Shield Users From Complexity
When a Nintex workflow fails due to an unexpected error, by default it sends an email message to the workflow initiator (i.e. the SharePoint user). This email message may contain a stacktrace, some cryptic message, or bits of code. The message does not explain (in plain English) how to fix the error, or who to contact to help resolve the error.
Therefore, instead of letting users see this email, it is advisable to send them to an IT administrator or an IT departmental email instead. This allows errors to be dealt with by the right person in a prompt manner.
When an item's properties are updated, the change is not guaranteed to be instantaneous! This can lead to "racing" issues, where we try to read the value of a column when it hasn't been updated yet.
For example, User A submits a vacation request. The workflow assigns User B to a approval task. User B approves the task, and enters a comment into the task. We then want to extract User B's comments and put it into an email. When we do a lookup in the task, we expect to get User B's new comment right? Wrong!
You see, if your Nintex workflow's "read" action is faster than the Microsoft SharePoint's "write" action, Nintex will will retrieve a value that isn't updated yet. In the example above, the workflow will unknowingly get a blank comment back from the task list.
Here is another example from Nintex's website:
The SharePoint workflow engine doesn’t necessarily commit batched operations in the order they are displayed on the designer. For example, if you had the following actions in this order:
- Set item permissions action (Nintex)
- Update list item action (Microsoft SharePoint)
- Set permissions action (Nintex)
These would actually execute in this order:
- Set permissions action (Nintex)
- Set permissions action (Nintex)
- Update list item action (Microsoft SharePoint)
To avoid these issues, insert the "Commit pending changes" action between actions where the prior action involves an update, and the subsequent action involves a read from the same item. The "Commit pending changes" action pushes all Microsoft batch actions and therefore ensures that subsequent read actions gives us the most recent data. Alternatively (but not ideally), you can use a "Pause workflow for..." action for 5 minutes instead of the commit action.
Bait And Switch
The Switch action in Nintex is a relatively new action that allows users to replace messy condition logic with a singular, cleaner looking logic statement. In many situations, using the Switch action is good way to test for multiple values, and to design workflows that are easier to read.
However, note that the Switch action is quite limited on how it can compare values. When we open up a Switch's configuration, we realize that we can only test if a variable is completely equal to another constant value. If our variable is coming from user input, or from a non-standardized/messy data source like AD or the User Profile Service, then we could potentially have more switch cases than we bargained for.
For example, we can have a text field which allows users to enter their department. Two users from HR might input their department name differently, like "HR" and "Human Resources". Another 3 users from IT department might enter "IT", "Information Technology", and "Info. Tech"). If we were to use a Switch action, our workflow would look like this:
If we have a few hundred users in 10 departments, you can easily imagine how messy this supposedly complexity-reducing action will become.
Therefore, in a scenario like this where your data is coming from unstandardized sources, it will be easier go back to the old way with "Set a condition" statements instead. For easier readability, consider wrapping all your conditions with a "Run paralled actions" action. Then, in your "Set a condition" statements, configure them such that you can compare the input variable with a range of values like so:
Using this method in the example, you can cover many comparisons in one branch and only need one branch per department. This is much better, and deserves a name like "Jeff's Awesome Improved Switch" or something similar :)
In my next post, I will offer some tips on Nintex forms. In the meantime, please feel free to leave any questions or comments below.