0

I am having a difficult time architecting the flow of declarative work to, and from, apex code.

What I want the flow to be is:

  1. Apex Trigger
  2. Flow (sends inputs to webservice)
  3. Webservice Callout (Process.Plugin or InvocableMethod)
  4. Flow (takes outputs from webservice)

My issues:

  1. Because you can not call a webservice from a Trigger, I must make the callout a future method. Because the callout is a future method, you cannot use static variables to return the value from the future method to the synchronous code that called it. Aka I can not pass back output parameters into the flow.
  2. Work Around 1: Create a process builder rather then the trigger to avoid future methods. Because of the order of DML and Callouts, I will always get an "Uncommitted Work Pending" error. The flow will make the DML and Callout loop thus causing DML to happen before and after the callout.
  3. Work Around 2: perform a DML update on the record after making the callout and do not pass back any parameters to the flow. Because of the async/sync differences between the callout, there is a delay between when the future method makes the insert and when the next block of the flow is fired. I need the Object to be inserted before it can move on to the next block in the flow. Due to the nature of the flow, it loops through multiple times thus causing the same error You have uncommitted work pending. Please commit or rollback before calling out

Does anyone have any suggestions (other then platform events) to allow the data to be passed to and from a flow and webservice? I feel like there must be a way to make option #1 work.

  • 1
    You can make callout form future method and update the response the record itself. – Kiran Machhewar Jan 15 '18 at 18:10
  • @KiranMachhewar I do not believe I can because future methods can not have a return value. – Olivia Jan 15 '18 at 18:11
  • That is true Olivia, it goes asynchronously. But you can update the result on the record itself. Tell this operation has to happen, is user using standard screen by which this request will be initiated or is there any custom screen. If custom screen is there then you can make real time synchronous callout. – Kiran Machhewar Jan 15 '18 at 18:15
  • @KiranMachhewar there is actually no UI at all. The process is all fired in the background off of the trigger. The trigger is fired off of a field change or a input of an Opportunity. – Olivia Jan 15 '18 at 18:19
  • If that is the case then do it in future. You will get the result in future method itself and then update the record itself. You don't need to depend on return value of future method. Inside future method when you get the result just update it on record. Consider future method as an async process where user is not waiting for response so you don't need to depend on direct real time result. – Kiran Machhewar Jan 15 '18 at 18:41
1

Platform Events was the only way for me to accomplish this. I didn't want to have to go this route because I would have to restructure my flow but it ended up being the only solution.

I created a custom Platform Event in SF and updated my webservice code to instantiate the event, and set the field values to the returned callout values. I subscribed to the event in a wait element in the flow and pulled back in the values from the webservice into the flow. I had to put a counter on the event so I was able to track accordingly for when there are multiple events coming in at the same time.

With this solution I was able to go: Apex Trigger -> Pass Input Parameters to Flow -> Call Webservice -> Pass Output Parameters back to Flow.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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