Search code examples
angulartypescriptnpmundefinedprimeng

Drawflow library on Typescript


I am currently trying to implement the awesome library Drawflow made by @Jerosoler (found here: https://github.com/jerosoler/Drawflow) inside my PrimeNg project.

Awesome user, @BobBDE made the typescript definition for this library here: https://www.npmjs.com/package/@types/drawflow

My project use PrimeNg with angular 11 and typescript 4.

I have used the 2 npm commands to install the library and the definitions. Everything is looking great. I can definetly find the JS library, and the definitions and use them inside Typescript.

However, I have an undefined error and I am struggling to find what am I doing wrong...

Inside my component html I have the following:

<div #drawflowDiv></div>

Retrieving the div inside my component typescript:

@ViewChild('drawflowDiv', {static: true}) 
drawflowDiv: HTMLElement;

Then inside my ngOnInit I have the following:

ngOnInit(): void {
    console.log(this.drawflowDiv);
    const editor = new drawflow(this.drawflowDiv);
    editor.reroute = true;
    editor.editor_mode = 'edit';
    editor.drawflow = {.....}; // Default example json for the library
    editor.start();
  }

I do not have any error anywhere in the code, the drawflow library is correctly linked. The console.log give me all the details of the div html element so it's not undefined. You'll find the screenshot of the console joined as a screenshot on this post.

Thank you in advance and hoping that maybe somebody here has a solution.

Thanks in advance!

enter image description here


Solution

  • to make the code reusable, you could also encapsulate everything in a directive:

    Directive file: ng-draw-flow.directive.ts

    import { Directive, ElementRef, OnInit } from '@angular/core';
    import Drawflow from 'drawflow';
    
    @Directive({
      selector: '[appNgDrawFlow]'
    })
    export class NgDrawFlowDirective implements OnInit {
    
      editor: Drawflow;
    
      constructor(private hostElRef: ElementRef) { }
    
      ngOnInit() {
        if (!!this.hostElRef?.nativeElement) {
          const { nativeElement } = this.hostElRef;
          this.initDrawFlow(nativeElement);
        }
      }
    
      private initDrawFlow(el: HTMLElement): void {
        try {
          if (!!el) {
            this.editor = new Drawflow(el);
            this.editor.reroute = true;
            this.editor.editor_mode = 'edit';
            // this.editor.drawflow = {}
            this.editor.start();
          } else {
            console.error('Drawflow host element does not exist');
          }
    
        } catch (exception) {
          console.error('Unable to start Drawflow', exception);
        }
      }
    }
    
    

    Remember to add NgDrawFlowDirective as a declaration to the parent feature module where you are using it.

    Template example for how to use it:

    <div appNgDrawFlow></div>
    

    If you have trouble getting it to run, double check your module declaration entry. For example (partial of app module):

    @NgModule(
      {declarations: [NgDrawFlowDirective]}
    )
    export class AppModule { }