Search code examples
angularjssummernote

angularjs component controller not passing initial binding value to directive in template (summernote)


I have this rather simple angularjs component that has an optional height binding:

"use strict";

angular
  .module("app")
  .component("myComp", getComp());

function getComp() {
  return {
    bindings: getBindings(),
    template: getTemplate(),
    require: "ngModel",
    controller,
  };
}

function getBindings() {
  return {
    height: "<?",
    noExternalFonts: "<?",
    ngModel: "=",
  }
}

function getTemplate() {
  return `<summernote height="$ctrl.height" ng-model="$ctrl.ngModel" config="$ctrl.options"></summernote>`
}

function controller(chSummernoteService) {
  const ctrl = this;
  ctrl.chSummernoteService = chSummernoteService;
  ctrl.$onInit = onInit.bind(ctrl);
}

function onInit() {
  const ctrl = this;
  ctrl.options = ctrl.chSummernoteService.getOptions({
    noExternalFonts: ctrl.noExternalFonts,
  });
}

The problem is, when I call it, the height is being ignored by summernote, the directive in the template, even tho the other two attributes, ng-model and options work fine.

<my-comp height="400" ng-model="$ctrl.someOtherCtrl></my-comp>

I also checked replated the $ctrl.height in the template with a hard coded number and that DOES work.

Is that some angularjs quirk I'm unaware of? (I'm new to angularjs, coming from React)

Or is that a bug in the summernote directive maybe?

Thanks in advance for any help!


Solution

  • I checked out the angular-summernote src and it appears to be bugged. Their controller is improperly written such that it reads the raw string value of the height attribute no matter what, so it's literally interpreted as "$ctrl.height". It's also written in such a way that it'll still read the raw value even if you try to force it in between interpolation bindings, i.e. height="{{ $ctrl.height }}" won't work either.

    Luckily, the config attribute is being parsed properly, and according to the documentation the height can be specified as a property within that instead. So remove the height attribute from your element and within your onInit function, add the height property to your config object:

    ctrl.options.height = ctrl.height;