2

I have a difficult question to explain and I'm way out of my comfort zone as far as expertise in Javascript, TrueType, Angular and MxGraph are concerned... Hope to be able to explain.

I have an Angular component displaying and MxGraph. I was able to integrate MxGraph with Angular following this link (How to integrate mxGraph with Angular 4?). Even if I use Angular 7, the solution still works...

The graph is displayed correctly on the page and everything works fine, including my override of the function graphHandlerMouseUp, which I do with this code:

// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
    mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
    mx.mxGraphHandler.prototype.mouseUp = function( graph, evt  ) {
      currentdropX = evt.graphX;
      currentdropY = evt.graphY;
      mx.graphHandlerMouseUp.apply(this, arguments);
    }

When I run this page for the first time, no problem happens.

Then through a button I call a page with another component (through routing). If from this page I go back to the first component (again through a routerlink) the page and the component with the MxGraph loads correctly, BUT when I use this function (i.e., release the mouse button).

It seems to me a recoursive problem, as when I put a console output like this:

// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
    mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
    mx.mxGraphHandler.prototype.mouseUp = function( graph, evt  ) {
      currentdropX = evt.graphX;
      currentdropY = evt.graphY;
      // INIFINTE LOOP HERE
      console.log("Test");
      mx.graphHandlerMouseUp.apply(this, arguments);
    }

The "Test" is written a number of times which is continuously growing. Yet, if I understood, this was the correct way of overriding the function. Of course on the first load of the page, "Test" is displayed once. Passing to another component and then back on this it is displayed an "infinite" number of times (until I reach the: "ERROR RangeError: Maximum call stack size exceeded")...

I tried also to remove that override, and besides the obvious lack of the functionality, the very same problem happened to the function "mxDragSource", which is overridden with the same approach.

As I said: I'm not expert enough in javascript, truetype, MxGraph or Angular, so any hint, even if obvious, is very welcome!

Thanks!

Marco
  • 246
  • 1
  • 9

1 Answers1

1

The first time you run your code, you store mx library's mouseUp event in a variable and you assign a new function to mouseUp event in which you call the old mouseUpEvent.

The second time you run your code, you store your current mouseUp event (that you have modified) and you assign a function in which you call the old mouseUpEvent, which is the same you stored previously. There goes your recursion !

What you need to do is override the third-party function properly, so you don't execute your code twice.

How to do it ?

You can create a mixin and use this mixin in your componentB/ If you have no idea what is it and how to do it, please reproduce your problem in a stackblitz I'll be glad to help you to implement it.

Florian
  • 1,473
  • 10
  • 15
  • Thanks for taking the time to reply! Yes I understood why the problem generates, the odd thing is that I can avoid this redefinition the second time simply looking if "mx.graphHandlerMouseUp" is already defined, and it works for this specific function, but I'm not that lucky with other functions of the same library (e.g. DragSource). I had a look into mixins but probably the first solution you propose is the best. Yet I think I still don't understand the lifecycle of the mx library throughout component routing... I was expecting this component to be "destroyed" leaving the page... – Marco Nov 08 '19 at 12:31
  • The component is indeed destroyed, but the library is cached. This is why the override is persisten through your components navigation. I'm sorry that I can help more with implementation without having much more code ! – Florian Nov 08 '19 at 13:06
  • Thanks Florian, you were already very helpful and the problem is now fixed... I would have a final question if that's not a problem... How can I force the reload of the library to avoid using the cached version? I'm asking because now there is no need for this, but in the future version also the first component will need a version of MXGraph library, where I will override functions. Most likely the same functions, but not necessarily all of them and not necessary only those functions... thanks again! – Marco Nov 10 '19 at 13:07
  • @Marco If you only need to override the library function in one component and this component is not duplicated in any view, you can use [ngOnDestroy](https://angular.io/guide/lifecycle-hooks#lifecycle-sequence). When you destroy the component, you reassign the library method that you previously had override – Florian Nov 11 '19 at 09:16