Search code examples
angulartypescriptinteractjs

using the injectable service in end callback function with interactJS


I'm using interactJS with angular to make it possible for the user to perform a drag and drop of the elements with the class 'draggable'. Everything worked fine until I needed to use the injected service of the component in in the callback function of the end drag. this is what I tried:

ngOnInit() {
    interact('.draggable')
        .draggable({
            inertia: true,
            modifiers: [
                interact.modifiers.restrictRect({
                    restriction: 'parent',
                    endOnly: true
                })
            ],
            autoScroll: true,
            listeners: { move: this.dragMoveListener, end: this.stackForUndo }
        })
}


stackForUndo() {
// get current state of svg
    let current_state = document.getElementById("Logo").outerHTML;

    // clear redo stack
    this.menuService.redo = {}

    // get the previous saved actions
    let actions = { elements: [] };

    // if no action has been cached, initialise the localStorage undo element
    if (actions == undefined) {
      actions = { elements: [] };

      // save stringified empty action to localStorage
      this.menuService.undo = actions;
    }

    // add the current state of the svg
    if(actions.elements.length >= 5){
      actions.elements.shift();
    }
    actions.elements.push(current_state);
    this.menuService.undo = actions;
}

after making a drag I couldn't drop the element and getting the folowing error in the browser console

Cannot read property menuService of undefined (in this.menuService.redo = {})


Solution

  • the root of your problem is that stackForUndo lost context, and for solving this I only binded it to the component as follow:

    ngOnInit() {
        interact('.draggable')
            .draggable({
                inertia: true,
                modifiers: [
                    interact.modifiers.restrictRect({
                        restriction: 'parent',
                        endOnly: true
                    })
                ],
                autoScroll: true,
                listeners: { move: this.dragMoveListener, end: this.stackForUndo.bind(this) }
            })
    }