infragistics igcselect web_component load event exception

17 views Asked by At

I'm trying to use the code to load the igcselect event listener in the constructor, however when I run it, the components of the page all disappear, the code is as follows,, and I'm not sure what's wrong with it:

import {html, css, LitElement} from 'lit';
import {customElement} from 'lit/decorators.js';
import {defineComponents, IgcInputComponent, IgcSelectComponent, IgcSelectItemComponent} from 'igniteui-webcomponents';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import {PyWorker, TYPES, config} from 'https://pyscript.net/releases/2024.1.1/core.js';
import {ModuleManager} from 'igniteui-webcomponents-core';
import {IgcMultiColumnComboBoxModule} from 'igniteui-webcomponents-grids';
import {IgcMultiColumnComboBoxComponent} from 'igniteui-webcomponents-grids';
import {IgcSelectEventMap} from "igniteui-webcomponents/components/select/select";

defineComponents(IgcSelectComponent, IgcInputComponent);
ModuleManager.register(IgcMultiColumnComboBoxModule);

@customElement('app-view1')
export default class View1 extends LitElement {
  private stockexchangeSelect: IgcSelectComponent;
  private futuresSelect: IgcMultiColumnComboBoxComponent;

  constructor() {
    super();
    this.stockexchangeSelect = document.getElementById("stockexchange_selector") as IgcSelectComponent;
    this.futuresSelect = document.getElementById("futures_selector") as IgcMultiColumnComboBoxComponent;

    this.stockexchangeSelect.addEventListener("igcChange", (evt) => {
      this.enrollmentcomponents(evt);
    });
  }

  private async enrollmentcomponents(e: CustomEvent<IgcSelectItemComponent>) {

    const worker = new PyWorker();

    config.packages = ['pandas', 'numpy', 'tushare', 'matplotlib'];
    config.paths = ['../src/pycontroller/updateViewController.py'];

    worker.script =
      'import updateViewController\n' +
      'bindingToJson(' + this.stockexchangeSelect.value + ')';
    await worker.run(TYPES.PYTHON, config);

    const ajaxactualconfig = {
      type: "post",
      url: "../src/pycontroller/updateViewController.py",
      dataType: "json"
    };

    this.futuresSelect.dataSource = this.ajax(ajaxactualconfig);
    this.futuresSelect.textField = "name";
    this.futuresSelect.valueField = ["ts_code"];
  }

however when I run it, the components of the page all disappear

1

There are 1 answers

0
wnvko On

Two things here:

  1. You cannot get the select by calling getElementById on Document, as it is under the shadow dom. You should call it over the shadow dom like this:
this.stockExchangeSelect = this.shadowRoot!.getElementById('stockExchange_selector') as IgcSelectComponent;
  1. The elements most probably will not be rendered in the constructor and trying to get the select will return null. You can solve this in several ways:
  • put your logic in request animation frame (note this may not work all the time):
constructor() {
  super();
  requestAnimationFrame(() => {
    this.stockExchangeSelect = this.shadowRoot!.getElementById('stockExchange_selector') as IgcSelectComponent;

    this.stockExchangeSelect.addEventListener("igcChange", (evt) => {
      this.enrollmentComponents(evt);
    });
  });
}
  • put your logic in firstUpdated lifecycle hook instead of in the constructor. This is the suggested way to do what you need - docs:
firstUpdated(e: any) {
  super.firstUpdated(e);
  this.stockExchangeSelect = this.shadowRoot!.getElementById('stockExchange_selector') as IgcSelectComponent;

  this.stockExchangeSelect.addEventListener("igcChange", (evt) => {
    this.enrollmentComponents(evt);
  });
}
  • finally you can add the handle in the markup. In this way you will not need to worry whether or not component is already rendered:
<igc-select @igcChange="${this.enrollmentComponents}">
  ... select items go here ...
</igc-select>