Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save SergeyAxenov/da15ace42e65a96d67bc6ac12362f64a to your computer and use it in GitHub Desktop.
Save SergeyAxenov/da15ace42e65a96d67bc6ac12362f64a to your computer and use it in GitHub Desktop.

Zeppelin 0.6.2. On angular watch initialization steps in client-first scenarious.

Zeppelin angular client-first

Zeppelin angular client-first is defined as an %angular paragraph with generated HTML output which is activated by an auto-run script:

<script>
changeValue($scope, value) {
	$scope.myValue=value
}
(function() {
	... 
	$scope.changeValue = angular.bind($scope, v => { changeValue($scope, v) });
	$scope.z.runParagraph(serverHandlerParagraphId);
})()
</script>

Therefore, the server side %spark paragraph is executed once setting up some angular watches to respond on client angular events

z.angularBind("myValue",null)
z.angularUnwatch("myValue")
z.angularWatch("myValue",(before,after,ctx) => {
	// server handler for myValue changes is here
})

Problem. Server-side angular watch is not always working

Serve-side angular watch handler is not triggered when angular variable on client is not initialized first or initialized as undefined:

<script>
changeValue($scope, value) {
	$scope.myValue=value
}
(function() {
	... 
	$scope.myValue=undefined
	$scope.changeValue = angular.bind($scope, v => { changeValue($scope, v) });
	$scope.z.runParagraph(serverHandlerParagraphId);
})()
</script>

Solution. Initialize angular variable on the client with dummy value

Serve-side angular watch handler is triggered when angular variable on client is initialized to some dummy value:

<script>
changeValue($scope, value) {
	$scope.myValue=value
}
(function() {
	... 
	$scope.myValue="None"
	$scope.changeValue = angular.bind($scope, v => { changeValue($scope, v) });
	$scope.z.runParagraph(serverHandlerParagraphId);
})()
</script>

The value doe not matter, because the first value the server side handler is going to recieve when triggered very first time will be null, due to server side initialization:

z.angularBind("myValue",null)

Test. Demo case

Create a new zeppelin note using the code below. Make sure paragraphId varaible points to your server side spark paragraph.

Negative case

1 Try to leave ax4value not initialized 2 Click buttons to see whether the changes trigger server side handler 3 Try to clone zeppelin note 4 Try to restart spark interpreter

Positive case

1 Initialize ax4value="None" 2 Click buttons to see whether the changes trigger server side handler 3 Try to clone zeppelin note 4 Try to restart spark interpreter

%angular
<div id="appContainer">
<div>
{{ax4message}} | Value: {{ax4value}}
</div>
<button ng-click="ax4setValue('Value 1')">Set 'Value 1'</button>
<button ng-click="ax4setValue('Value 2')">Set 'Value 2'</button>
<button ng-click="ax4setValue(undefined)">Set 'undefined'</button>
</div>
<script>
function ax4setValue($scope, value) {
$scope.ax4message=new Date().getTime();
$scope.ax4value=value;
}
(function() {
var paragraphId = '20170319-223646_1841133911'
var el = angular.element($('#appContainer').parent('.ng-scope'));
if (el) {
var $scope = el.scope().compiledScope;
if ($scope) {
// debugger;
console.log("Attached to angular scope ...")
$scope.ax4message="Attached to angular scope"
// Try to delete value initialization or set it undefined
// $scope.ax4value=undefined
$scope.ax4value="None"
$scope.ax4setValue = angular.bind($scope, v => { ax4setValue($scope, v) });
$scope.z.runParagraph(paragraphId);
}
}
})()
</script>
z.angularBind("ax4value",null)
z.angularUnwatch("ax4value")
z.angularWatch("ax4value",(before,after,ctx) => {
val message = s"Watch triggered. Old value=$before New value=$after"
z.angularBind("ax4message",message)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment