ngHandsontable afterChange triggers twice (PRO)

Tags: #<Tag:0x00007efc6254ac08>

Hi,

In my ngHandsontable application I have need for both beforeChange and afterChange events. Problem is that afterChange gets triggered twice for the each cell which is causing me a lot of trouble.

This happens even when I comment out everything from it (and from all other events). Is that some common problem? How to prevent it from triggering twice?

These are my settings:

	$scope.spreadsheet.settings = {
		beforeChange: (changes: Array<any>, source) => {
			// commented out
			changes.forEach(val => {
				var hot = hotRegisterer.getInstance($scope.spreadsheet.hotInstanceID);
			});
		},
		afterChange: (changes: Array<any>, source) => {
			// commented out
			// if one of this source types - its UPDATE
			if (["autofill", "alter", "edit", "paste"].indexOf(source) !== -1) {
				// change - row, prop, old, new
				changes.forEach(val => {
					var hot = hotRegisterer.getInstance($scope.spreadsheet.hotInstanceID);
				});
			}
		},
		beforeValidate: (value, row, prop, source) => {
			// commented out
		},
		afterValidate: (isValid, value, row, prop, source) => {
			// commented out
		},
		dropdownMenu: true,
		filters: true,
		columnSorting: true,
		sortIndicator: true,
		startRows: 50,
		fixedColumnsLeft: 2,
		viewportRowRenderingOffset: 15,
		viewportColumnRenderingOffset: 50,
		manualColumnResize: true,
		renderAllRows: true,
		wordWrap: true,
		stretchH: 'all',
		undo: false,
		columns: $scope.visibleColumns,
		cells: (row, col, prop) => {
			var cellProperties: any = {};
			if (col === 0) {
				cellProperties.renderer = idColumnRenderer;
			}

			if (readOnlyColumns.indexOf(prop) >= 0) {
				cellProperties.readOnly = true;
			}

			return cellProperties;
		}
	};

And this is markup

<hot-table hot-id="{{spreadsheet.hotInstanceID}}"
           settings="spreadsheet.settings"
           min-spare-rows="spreadsheet.minSpareRows"
           datarows="spreadsheet.data" >
</hot-table>

Hi @danijel.dukaric
I would be much better if you could create a working Fiddle. Can you take a minute to prepare one?

Hi @aleksandra_budnik

I’m not sure how to reproduce it, I tried to play with examples and modify sources, but here is what I’ve found out, hopefully it can help you guys to maybe identify a problem.

After some digging through source code and example at http://handsontable.github.io/ngHandsontable/demo/index.html#/intro-simple-example
(I’ve extended example with simple afterChange that only logs change) I found out following:

When I edit cell handsontable will trigger applyChanges which will call
Handsontable.hooks.run(instance, 'afterChange', changes, source || 'edit');

After the hook is run,localHandlers array has 3 handlers both in my case and in example. Difference is that in example they are

[scope.htSettings.afterChange(), anonymous(changes, origin), onAfterChange(changes, source)]

and in my case they are

[scope.htSettings.afterChange(), anonymous(changes, source), $scope.spreadsheet.settings.afterChange(changes, source)]

– Notice the difference at the last element of localHandlers array - in example it is onAfterChange (the one from handsontable itself), while in my case it is call to afterChange in my settings object - that will cause handsontable to trigger afterChange event again (localHandler[0] is responsible for the first trigger, which is okay).

Any idea on this?

Hi Dan,

I would have to ask our devs to look at this issue as I’m not familiar with ngHandsontable.

Thank you very much Aleksandra…

Most important question here is why is my afterChange event handler at the end of localHandlers which causes it to be triggered twice

1 Like

Hi @danijel.dukaric unfortunately there has to be something on your side.

Our developer Krzysztof was testing the case and the logs are always coming single as they should. Here’s a demo he made: http://jsbin.com/gufemigeju/1/edit?html,js,console,output

Thanks for reply @aleksandra_budnik,

i managed to track source of problem - it was updateSettings call after which my afterChange handler was pushed to the localHandlers. I removed that call and now it works fine

Thanks for an update @danijel.dukaric
I was curious about what was the case - I’m glad that you solved this case.

Have great day!