Finding angular scope from javascript
No edit summary
(Automatically adding template at the end of the page.)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Working with EXT_Components and integrating towards other services you may end up in situations where you get callbacks in client side javascript - and you will want to catch data from such a callback.  
When working with EXT_Components and integrating towards other services, you may end up in situations where you get callbacks in client-side javascript - and you will want to catch data from such a callback.  


To get hold of your objects from such a callback (that are outside of the normal angular realm where you have some scope information at hand) you can go like this:
To get hold of your objects from such a callback (that are outside of the normal Angular realm where you have some scope information at hand), you can do this:
  var vmroot=angular.element('#viewmodelWrapper').controller().$scope.ViewModelRoot;
  var vmroot=angular.element('#viewmodelWrapper').controller().$scope.ViewModelRoot;
You now have the current local representation of your ViewModel in the vmroot variable and you can set properties like this:
You now have the current local representation of your ViewModel in the vmroot variable and you can set properties like this:
  vmroot.MyViewModelColumn=somevalueFromACallBack;
  vmroot.MyViewModelColumn=somevalueFromACallBack;
MDrivenTurnkey sees the property you change and handles signaling of server and binding of UI.
MDrivenTurnkey sees the property you change and handles the signaling of the server and binding of UI.


With some defensive error checking:
With some defensive error checking:
Line 16: Line 16:
       }
       }


=== Alternative approach ===
=== Alternative Approach ===
Depending on what your needs are it may be better to inject the result into a UI control and let AngularJS handle the databinding to move that data into the underlying ViewModel-object-column-property (then Turnkey will discover the change and stream it to the server). In order to let angularjs know that the code you use to set the value should be handled as a user interaction of the input you must dispatch the change event. Something like this:
Depending on what your needs are, it may be better to inject the result into a UI control and let AngularJS handle the databinding to move that data into the underlying ViewModel-object-column-property (then Turnkey will discover the change and stream it to the server). To let AngularJS know that the code you use to set the value should be handled as a user interaction of the input, you must dispatch the change event. Something like this:
  function setResult(label, result) {
  function setResult(label, result) {
   let someelem=document.getElementById('BiljettCheck.Id');  // find the input elem bound to ViewModel "BiljettCheck" and Column "Id"
   let someelem=document.getElementById('BiljettCheck.Id');  // find the input elem bound to ViewModel "BiljettCheck" and Column "Id"
Line 25: Line 25:
  }
  }


=== Acting after angular page has fully loaded ===
=== Acting after Angular Page Has Fully Loaded ===
The script below can be added to your page and it will call a function startTheProcess after the data has been bound in Angular (data need not have downloaded - but it is bound bu angularjs)
The script below can be added to your page and will call a function StartTheProcess after the data has been bound in Angular (data need not have been downloaded - but it is bound by AngularJS)
  angular.element(function () {
  angular.element(function () {
   console.log('page loading completed');
   console.log('page loading completed');
   startTheProcess();
   startTheProcess();
  });
  });
You can then use angularjs functions like $watch to find out when data is available or changed like this (this example was taken from a bank integration for easyarr - Swedbank ):
You can then use AngularJS functions like $watch to find out when data is available or changed like this (this example was taken from a bank integration for EasyArr - Swedbank):
<pre>
<pre>
         var initiated=false;
         var initiated=false;
Line 77: Line 77:
}
}
</pre>
</pre>
[[Category:Debugging]]
{{Edited|July|12|2024}}

Latest revision as of 15:34, 10 February 2024

When working with EXT_Components and integrating towards other services, you may end up in situations where you get callbacks in client-side javascript - and you will want to catch data from such a callback.

To get hold of your objects from such a callback (that are outside of the normal Angular realm where you have some scope information at hand), you can do this:

var vmroot=angular.element('#viewmodelWrapper').controller().$scope.ViewModelRoot;

You now have the current local representation of your ViewModel in the vmroot variable and you can set properties like this:

vmroot.MyViewModelColumn=somevalueFromACallBack;

MDrivenTurnkey sees the property you change and handles the signaling of the server and binding of UI.

With some defensive error checking:

      function GetVMRoot(){
	var ctrl=angular.element('#viewmodelWrapper').controller();
        if (ctrl !== undefined){
           return ctrl.$scope.ViewModelRoot;
        }					
        return undefined;      
      }

Alternative Approach

Depending on what your needs are, it may be better to inject the result into a UI control and let AngularJS handle the databinding to move that data into the underlying ViewModel-object-column-property (then Turnkey will discover the change and stream it to the server). To let AngularJS know that the code you use to set the value should be handled as a user interaction of the input, you must dispatch the change event. Something like this:

function setResult(label, result) {
  let someelem=document.getElementById('BiljettCheck.Id');   // find the input elem bound to ViewModel "BiljettCheck" and Column "Id"
  someelem.value=result;                                     // assign a new value to the input
  var event = new Event('change');    
  someelem.dispatchEvent(event);                             // signal to listeners (angularjs) that the value has changed
}

Acting after Angular Page Has Fully Loaded

The script below can be added to your page and will call a function StartTheProcess after the data has been bound in Angular (data need not have been downloaded - but it is bound by AngularJS)

angular.element(function () {
  console.log('page loading completed');
  startTheProcess();
});

You can then use AngularJS functions like $watch to find out when data is available or changed like this (this example was taken from a bank integration for EasyArr - Swedbank):

        var initiated=false;	
	function startTheProcess() {
				
		console.log('startTheProcess');
		//debugger;
		var thescope=angular.element('#viewmodelWrapper').controller().$scope;
		if (!initiated){
			initiated=true;
			thescope.$watch('ViewModelRoot.DataIsLoaded', function (newv, oldval, thescope) {
				console.log('startTheProcess WATCH DataIsLoaded '+newv);
				if (newv=="DataIsLoaded"){
					thescope.ViewClient.CallServerAction('SwedbankPay','SCRIPTSCALLCheckIn',null); // handles the case when we called CheckIn too early 
				  }
				});
			thescope.$watch('ViewModelRoot.FetchedScriptUrlForCheckin', function (newv, oldval, thescope) {
				console.log('startTheProcess WATCH FetchedScriptUrlForCheckin '+newv);
				if (newv && newv!=""){
					  DoCheckInScript(newv,thescope);
				  }
				});
			thescope.$watch('ViewModelRoot.FetchedScriptUrlForPaymentUI', function (newv, oldval, thescope) {
				console.log('startTheProcess WATCH FetchedScriptUrlForPaymentUI '+newv);
				if (newv && newv!=""){
					  DoPaymentUIScript(newv,thescope);
				  }
				});
			thescope.$watch('ViewModelRoot.ConsumerId', function (newv, oldval, thescope) {
				console.log('startTheProcess WATCH ConsumerId '+newv);
				if (newv && newv!=""){
					  DoPaymentOrderForThisConsumerProfile(newv,thescope);
				  }
				});
				
			
		}
		else{
				console.log('startTheProcess - init skipped');
		}

		thescope.ViewClient.CallServerAction('SwedbankPay','SCRIPTSCALLCheckIn',null)
		console.log('startTheProcess CheckIn');
	
	}
This page was edited 99 days ago on 02/10/2024. What links here