Use PDIs? Take our 5-minute survey to help shape the PDI roadmap.

Add a custom field to Todos HR Case Approval widget

Padraig O_Kane1
Tera Contributor

I have a requirement to introduce a Second Approver field on the HR Case Approval widget that is then passed to the Approval record and updated. I have cloned the out of the box widget and made the following changes (see screenshot 1 where I have introduced the new field, server logic to pull back a list of users and broadcast logic to check for changes to the field - this is needed as the widget relies on an embedded widget where the Approve/Reject buttons are located). The issue I am having is passing the new field value to the embedded widget (see screenshot 2 where I have introduced a listener for field changes). I have also made changes to the script include but whenever I log the secondApprover value it is empty or doesn't appear in the request output). Any help would be great. 

1 ACCEPTED SOLUTION

@Padraig O_Kane1:  Ah, looking closely at your screenshots, a few small variable reference mismatches could be quietly breaking the chain! In your parent client script, c.onRecordChange is trying to broadcast $scope.data.secondApprover, but your <sn-record-picker> actually writes to c.secondApprover (and you'll want to send c.secondApprover.value over). Then, over on the child side, $scope.$on is receiving that payload and setting c.data.secondApprover to the entire event object (obj) instead of obj.secondApprover. Finally, in your child server script , data.secondApprover isn't defined yet on the server, so you'll want to grab input.request.secondApprover directly. If you clean up those three variable assignments, that value should flow right on through to your backend process! You can try the following:

  • Update Parent Client Script: Broadcast c.secondApprover.

  • Update Child Client Script: Set c.data.secondApprover = obj.secondApprover.

  • Update Child Server Script: Use input.request.secondApprover instead of data.secondApprover.

 

View solution in original post

10 REPLIES 10

KPNow
Kilo Guru

The probable reason your secondApprover value is coming up empty is perhaps due to an asynchronous timing issue in your embedded widget's client script specifically, you are defining the $scope.$on('data-updated') listener inside your sendUpdateRequest() function right before creating c.data.request. Because $scope.$on sets up an event listener for future broadcasts rather than executing synchronously on the spot, c.data.secondApproverremains undefined when c.server.update() fires. To fix this, move the $scope.$on('data-updated', ...) listener out of sendUpdateRequest to the top level of your embedded widget's client controller so it constantly listens for changes, update your broadcast in the parent widget to pass an object like $rootScope.$broadcast('data-updated', { secondApprover: $scope.data.secondApprover }), and then extract input.request.secondApproveron the server script before handing it off to your Script Include.

Hope this helps.

Padraig O_Kane1
Tera Contributor

Thanks KPNow, I'll make the updates you suggested and let you know if it worked. Appreciate it. 

Padraig O_Kane1
Tera Contributor

Unfortunately that hasn't worked @KPNow . The output from the script include still doesn't contain any reference to the second approver. When using broadcast and on, do I need to pass anything within this function: (Approval Actions widget): 

 

 function sendUpdateRequest(state, action, comment) {
 
        c.data.action = action;
        c.data.sysId = c.data.sysId;
        c.data.commentId = c.data.commentId;
        c.data.commentTable = c.data.commentTable;
        c.data.useCommentBox = c.data.useCommentBox;
        c.data.request = {
            state: state,
            comments: comment, 
            secondApprover: c.data.secondApprover,//POK
        };
        c.server.update();
    }
 
Or by having broadcast and on, we no longer need to build the request object? 

When passing data between embedded Service Portal widgets, it helps to think of the $broadcast event as just a local handoff between two client controllers. Raising the broadcast doesn't automatically talk to the server or bypass the payload setup—it simply hands the secondApprover value to your child widget so it can hang onto it. Because of that, you definitely still need to build the c.data.request object inside sendUpdateRequest(). Without explicitly adding secondApprover: c.data.secondApprover to that object, the child widget's client controller won't include it when c.server.update() finally fires off to the server.

If your Script Include is still coming up empty after keeping that request object intact, the break in the chain is almost certainly on the child widget's Server Script. When c.server.update() triggers, all that client-side data lands in the server script's input object. Make sure your child widget's server logic is specifically looking for input.request.secondApprover and actually forwarding that value as a parameter when it calls your Script Include function. Once you verify the child server script extracts that property from input and hands it off, the Script Include will finally catch the value and write it to the record. Hope this helps you.