the-graph icon indicating copy to clipboard operation
the-graph copied to clipboard

Cannot read properties of undefined (reading 'length')

Open linonetwo opened this issue 1 year ago • 3 comments

Cannot read properties of undefined (reading 'length')
TypeError: Cannot read properties of undefined (reading 'length')
    at eval (webpack-internal:///./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/the-graph/the-graph/the-graph-graph.js:489:58)
    at Array.map (<anonymous>)
截屏2023-07-11 19 09 07

only inPorts and outPorts exists on component, no inports, so inports is undefined.

var componentInfo = self.props.library[node.component];

        if (TheGraph.config.autoSizeNode && componentInfo) {
          // Adjust node height based on number of ports.
          var portCount = Math.max(componentInfo.inports.length, componentInfo.outports.length);

I get library by this, there is no doc on this, I read the source to learn this:

/* eslint-disable @typescript-eslint/strict-boolean-expressions */
/* eslint-disable @typescript-eslint/promise-function-async */
import { useThemeObservable } from '@services/theme/hooks';
import { type Graph, loadJSON } from 'fbp-graph/lib/Graph';
import { ComponentLoader } from 'noflo';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import type { IFBPLibrary } from 'the-graph';
import { GraphEditor } from './GraphEditor';
import { photoboothJSON } from './photobooth.json';

export default function Workflow(): JSX.Element {
  const { t } = useTranslation();
  const theme = useThemeObservable();

  const [library, setLibrary] = useState<IFBPLibrary | undefined>();
  const [graph, setGraph] = useState<Graph | undefined>();
  useEffect(() => {
    void loadJSON(photoboothJSON).then(graph => {
      setGraph(graph);
    });
  }, []);
  // load library bundled by webpack noflo-component-loader from installed noflo related npm packages
  useEffect(() => {
    const loader = new ComponentLoader('');
    void loader.listComponents().then((componentList) => {
      const libraryToLoad: IFBPLibrary = {};
      Object.entries(componentList).forEach(([name, componentDefinitionRaw]) => {
        if (typeof componentDefinitionRaw === 'string') {
          // TODO: handle these ComponentDefinition types
          return;
        }
        if ('getComponent' in componentDefinitionRaw) {
          const componentDefinition = componentDefinitionRaw.getComponent();
          libraryToLoad[name] = componentDefinition;
        }
      });
      setLibrary(libraryToLoad);
    });
  }, []);
  return graph && library
    ? (
      <>
        <GraphEditor theme={theme?.shouldUseDarkColors ? 'dark' : 'light'} library={library} graph={graph} />
      </>
    )
    : <div>{t('Loading')}</div>;
}

So library constructed from noflo's new ComponentLoader().listComponents()[0].getComponent() is not assignable to <TheGraph.App />?

linonetwo avatar Jul 11 '23 11:07 linonetwo

https://github.com/noflo/noflo-ui/blob/22d26eca71b52cd5181dd253f76bdb13c6bfecd4/src/runtime.js#L25-L33

Why this, can you just replace all inports to inPorts so this is compatible with noflo (which has ts typing?)

linonetwo avatar Jul 11 '23 15:07 linonetwo

Who is sending this?

https://github.com/noflo/noflo-ui/blob/22d26eca71b52cd5181dd253f76bdb13c6bfecd4/components/RuntimeReducer.js#L74-L76

Anyone knows? I need to find ts type for componentForLibrary's input, it is not Component from import { Component } from 'noflo'; which only have icon and description but no inPorts

Seem to be this https://github.com/noflo/noflo-runtime-base/blob/36ff1a439e1df9ad7611afd3cda908cce9e14fe2/src/protocol/Component.js#L202-L209

runtime:components is no used anywhere, only runtime:component is used and is send from here.

linonetwo avatar Jul 11 '23 16:07 linonetwo

This is wrong

截屏2023-07-12 01 05 35

the component from getComponent() is really a class Component extends EventEmitter, so can't use componentForLibrary on it.

linonetwo avatar Jul 11 '23 17:07 linonetwo