Power Automate
How to stop infinite flow trigger in Power Automate using CSOM

How to stop infinite flow trigger in Power Automate using CSOM

Infinite flow trigger is a common scenario in workflow softwares like Nintex, K2 and even in Power Automate. There is a classic way of handling it by using the flag column with form, flag column without form.

In classic SharePoint sites, Javascript can be injected in the form load, we can use that to set the flag variables, but in modern versions, it is not possible to inject scripts on form load.

Let’s see some scenarios in which the flow will trigger infinitely,

  1. Workflow trigger on item update – If the workflow updates the same item again then flow will trigger infinitely.
  2. Workflow trigger on item create – If the workflow creates a item in the same list then flow will trigger infinitely.

Before the CSOM solution, we will see how the default update actions and Rest API methods are working. In this example, we will see the “workflow trigger on item update“.

Default Update action

Created a workflow with the trigger as item update and updating an item.

Simple Update item action

Once the item is updated as we can see the flow is triggered infinitely.

Rest API method

SharePoint has a lot of endpoints to communicate with its components. We are going to use a rest API Post method to update an item. Here we are not going to discuss more on the rest API explanation it will be covered in a separate post.

Created a POST method with the respective URI and passed the inputs in JSON format.

Rest API update method

Once the item is updated the flow triggers infinitely. Even there is no System Update in Rest API but there is a similar method called “ValidateUpdateListItem” using that we can replicate close to System Update. But it stops preventing loops now, So this method is eliminated.

CSOM Update

Here we used “Send an HTTP request action” to send requests to SharePoint, anyone who worked in CSOM, JSOM would be familiar with the below XML format.

CSOM and JSOM will have the “System Update” method which the backend system never considers as an event and no versions will be created on that item. So the workflow will not trigger, even in Nintex workflow there is an action called “Set Item” which will update the item but never triggers the workflow.

  1. Here we can see the method as “SetFieldValue”
  2. The column name and value is passed in parameters
  3. Here we passed the GetList method
  4. Relative URL of the list
  5. Which method is going to be performed.
  6. Since it is “GetItemById”, ID is passed.

1 and 2 represent the action to be performed (it is enclosed inside ) here it is System Update. 3,4,5 and 6 represent where the action should be performed.

Below is the JSOM code for System Update, but it requires sp.js to run in that context. Here we are sending a request from Power Automate which is not in the SharePoint context, so we can use CSOM API it does not require SP libraries.

const ctx = SP.ClientContext.get_current();

const list = ctx.get_web().get_lists().getByTitle('Infinite Loop');
const item = list.getItemById(1);

item.set_item('Title', 'Loop');
// item.update(); // -> creates new version, updates Editor and modified date
// item.updateOverwriteVersion(); // -> creates no new version, updates Editor and modified date
item.systemUpdate(); // -> creates no new version, Editor and modified date remains untouched

ctx.executeQuery(success, failure);

CSOM API Request

var listRelativeUrl = '/sites/site name/Lists/Infinite Loop';
var itemId = 1;

var body = `
  <Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Javascript Library">
    <Actions>
      <Method Name="SetFieldValue" Id="4" ObjectPathId="3">
        <Parameters>
          <Parameter Type="String">Title</Parameter>
          <Parameter Type="String">Loop</Parameter>
        </Parameters>
      </Method>
      <Method Name="SystemUpdate" Id="5" ObjectPathId="3" />
    </Actions>
    <ObjectPaths>
      <Property Id="1" ParentId="0" Name="Web" />
      <Method Id="2" ParentId="1" Name="GetList">
        <Parameters>
          <Parameter Type="String">${listRelativeUrl}</Parameter>
        </Parameters>
      </Method>
      <Method Id="3" ParentId="2" Name="GetItemById">
        <Parameters>
          <Parameter Type="Number">${itemId}</Parameter>
        </Parameters>
      </Method>
      <StaticProperty Id="0" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" />
    </ObjectPaths>
  </Request>
`;

const endpoint = `${siteUrl}/_vti_bin/client.svc/ProcessQuery`;
const client = new SPHttpClient();

client.post(endpoint, {
  headers: {
    'Accept': '*/*',
    'Content-Type': 'text/xml;charset="UTF-8"',
    'X-Requested-With': 'XMLHttpRequest'
  },
  body
})
  .then(r => r.json())
  .then(r => {
    if (r[0].ErrorInfo) {
      throw new Error(r[0].ErrorInfo.ErrorMessage);
    }
    return r;
  });

The above XML package will be prepared in the JSOM library and it will be sent to Execute Query method. Here we are creating the XML queries manually and directly passing them to the “client.svc” method.

Now we will update the item to see whether the flow is triggered more than one time.

The “ErrorInfo” is null that means the value is updated properly.

This may be good to update fewer columns, If there are more columns definitely it will be chaotic to see the whole XML again. There are some limitations in updating the multi-select (People picker, Lookup) columns do check it out before considering this approach.

Reference Link

To update other column types, Kindly let us know in the comments. Happy Building 🙂

0

Leave a Reply

Newsletter Signup

Subscribe to our weekly newsletter below and never miss out the latest updates

%d bloggers like this: