Tuesday, April 23, 2019

Disable Event Firing when Flow updates a SharePoint list item


There’s a lengthy discussion over at https://powerusers.microsoft.com/t5/Flow-Ideas/Disable-Event-Firing-when-Flow-updates-a-SharePoint-list-item/idc-p/271110 to have a Flow trigger on a SharePoint item being modified, and then be able to update that same item in the workflow without causing it to re-trigger, causing a possible infinite loop.

The workaround posted so far is to check on a specific field if you are to update the item or not. This causes Flow to fire twice per item, one for the actual update, and one where it skips the update based on some status logic.

Melissa Hubbard has a post on the workaround solution over at THE INFINITE LOOP: WHAT IT IS AND HOW TO AVOID IT.

[Update]
It is also possible to use the ValidateUpdateListItem REST API as well, but you need to ensure you get the dates formatted correctly. I could not make it work for Norwegian locale, but once setting the locale to English I got it working. Examine the output of the action after a test run to see if dates had issues or not.

A big thank you to John Liu for pointing this out, as I missed the trick of setting the date when testing this API when researching this post.

http://johnliu.net/blog/2019/2/flowninja-hack-78-modifying-modified-by-and-modified-time-with-microsoft-flow

As an update to the JSON payload used in John's post, set bNewDocumentUpdate to true, if you don't want to add a new version to the item you are updating (kind of counter-intuitive).



[Original Post]

The underlying issue causing this behavior is that any update to a SharePoint item will trigger an update event for the list. EXCEPT if you use a method called SystemUpdate, which is only available via the JSOM/CSOM/Native SharePoint API’s, and not the REST API.

This quickly becomes very technical, but until the SharePoint Flow connectors support the ability to update using a System Update, this is what we have to deal with. It is certainly possible to overcome this issue, but it involves a bit of XML which might throw you off. If not, read on.

Andrew Koltyakov has a good explanation of how System Update works and can be accomplished in his blog post List Items System Update options in SharePoint Online. I’ll reuse a bit from Andrew’s post to show how you using the SharePoint HTTP connector can accomplish a system update from Flow.



In order to update your item add a Send an HTTP request to SharePoint action to your flow with the following parameters:
  • Site address: URL of your site
  • Method: POST
  • Uri: _vti_bin/client.svc/ProcessQuery
  • Headers:
    • Content-Type: text/xml;charset="UTF-8"
    • X-Requested-With: XMLHTTPRequest
    • Accept: */*
  • 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">yo</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">/sites/test2/Lists/LocationList</Parameter>
                </Parameters>
            </Method>
            <Method Id="3" ParentId="2" Name="GetItemById">
                <Parameters>
                    <Parameter Type="Number">@{triggerBody()?['ID']}</Parameter>
                </Parameters>
            </Method>
            <StaticProperty Id="0" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" />
        </ObjectPaths>
    </Request>
    
The important parts in the XML are line 5 and 6 which sets the name of the field to update and the value you want to set, line 15 which points to the relative URL of the list to update, and line 20 which has the ID of the item to update.

If you want to update more than one field, you would add more <Method> sections, but remember to give them a different sequential Id. This means that all <Method> tags should have a unique id in the <Actions> block.

If you manage to get everything set up correctly, your item should update just fine, without adding a new version and without firing an update event.

If you want to update a value beside a string, you need to change line 6 from String to another supported data type like  Boolean, DateTime or Number (a complete list of supported types can be found in the xml schema documentation).

Note: I have not dug into how to set for example people, lookup and taxonomy fields using this approach, but it’s certainly doable and you can check the network trace for JSOM/CSOM calls if you are developer to see what is actually being sent.

Happy Flowing!

References:
Cover photo by Tine Ivanič at Unsplash

3 comments:

  1. I have been using the technique in the link below for the past 12 months with great success. Flow being a subset of Logic Apps, it is quite easy to add a Condition to the SharePoint trigger to only run under certain conditions. I use this all the time to prevent the trigger on dates, booleans, and just about any metadata on my SharePoint list items. I update the metadata the first time I trigger the Flow and then the second time the trigger is skipped and the Flow run does not count towards your quota. It is fairly straight forward to add the condition to the trigger in the exported JSON and re-import and you are good to go. I have found I can still edit the Flow multiple times without losing the hidden condition on the trigger. Iusually put a comment on the trigger to indicate there is a hidden condition and what it is for other Flow editors to see.
    This is the reference I used :
    https://sergeluca.wordpress.com/2018/04/11/trigger-your-flow-only-when-a-document-is-created-from-a-specific-content-type/

    ReplyDelete
    Replies
    1. I'm aware of this solution, and guess this might be just as easy depending on your skills :)

      Delete
  2. is there anyway to update a person field using this method? I can't get any value to work

    ReplyDelete