Calling widget's client controller from Body HTML script tag

Nisar2
Mega Guru

I've the following in the Body HTML template of widget.

 

Nisar2_0-1698236053729.png


The alert is working. But I've not been able to figure out how to pass that info to the client controller or server side. Any suggestions?

1 ACCEPTED SOLUTION

I have never tried pulling in React in Service Portal, but the following might work.

In the client controller define some variables on $scope or c.

api.controller = function($scope){
    var c = this;
    $scope.geoLoc = {
        "lat": "",
        "long": ""
    };
    
    //to test if this works watch the variables for changes and log out values
    $scope.$watch( 'geoLoc ', function (newValue, oldValue ) {
        if(newValue.lat || newValue.long)
            console.log(newValue)
    }, true)
...
}

 

Since your React script is outside AngularJS scope you'll need to grab it within the script tags in the HTML template. You'll also want to wrap within a setTimeout to ensure the elements are present before the script runs.

 

  <script>
    
    setTimeout(function(){
        var scope = angular.element('#Geo_Map_root').scope();
        let locTimer;
        const loadLocationMap = () => {
          const { LocationMap } = window.geoJsLib;
          const root = ReactDOM.createRoot(document.getElementById('Geo_Map_root'));
          const onSubmit=(location) => {
            scope.geoLoc.lat = location.latitude.toString();
            scope.geoLoc.long = location.longitude.toString();
          }
          root.render(React.createElement(LocationMap, { onSubmit }, null));
        }
    },500);
    
  </script>

 

I know that doing this works without using React, so theoretically it should work with it.

react_test.gif

View solution in original post

8 REPLIES 8

Nisar2
Mega Guru

Hi all,

 

Any suggestions for this?

I have never tried pulling in React in Service Portal, but the following might work.

In the client controller define some variables on $scope or c.

api.controller = function($scope){
    var c = this;
    $scope.geoLoc = {
        "lat": "",
        "long": ""
    };
    
    //to test if this works watch the variables for changes and log out values
    $scope.$watch( 'geoLoc ', function (newValue, oldValue ) {
        if(newValue.lat || newValue.long)
            console.log(newValue)
    }, true)
...
}

 

Since your React script is outside AngularJS scope you'll need to grab it within the script tags in the HTML template. You'll also want to wrap within a setTimeout to ensure the elements are present before the script runs.

 

  <script>
    
    setTimeout(function(){
        var scope = angular.element('#Geo_Map_root').scope();
        let locTimer;
        const loadLocationMap = () => {
          const { LocationMap } = window.geoJsLib;
          const root = ReactDOM.createRoot(document.getElementById('Geo_Map_root'));
          const onSubmit=(location) => {
            scope.geoLoc.lat = location.latitude.toString();
            scope.geoLoc.long = location.longitude.toString();
          }
          root.render(React.createElement(LocationMap, { onSubmit }, null));
        }
    },500);
    
  </script>

 

I know that doing this works without using React, so theoretically it should work with it.

react_test.gif

Brilliant answer. It does work. However, it takes a good 10-15 seconds for the watch() to trigger (after onSubmit() function is executed)

 

Is that normal or can something be done about it? I've written the code to send that info to server side but given that it's taking a long time to trigger, I'm wondering if that would be a good UX.

chrisism
Tera Contributor

-