Search code examples
javascriptnode.jsnoflo

noflo: Dynamic component loading - Component [name] not available with base [path]


I am getting the error:

Component [name] not available with base [path]

when trying to dynamically attach components to a network's ComponentLoader instance.

var components = []; // This is populated with noflo.Component instances at runtime.
var graph = {
    properties: { name: 'Test components' },
    processes: {
        log: { component: 'log' },
        split: { component: 'split' }
    },
    connections: [
        {
            data: 'John Doe',
            tgt: { process: 'split', port: 'in' }
        },
        {
            src: { process: 'split', port: 'left' },
            tgt: { process: 'log', port: 'in' }
        },
        {
            src: { process: 'split', port: 'right' },
            tgt: { process: 'log', port: 'in' }
        }
    ]
};

noflo.graph.loadJSON(graph, function(g) {

    noflo.createNetwork(g, function(n) {

        var getComponent = function(c) {
            return c;
        }

        for (var i = 0; i < components.length; i++) {

            var c = components[i];
            n.loader.components[c.key] = {};
            n.loader.components[c.key].getComponent = getComponent.bind(null, c);

        };

    });
});

I have also tried assigning the component directly to the property for the components collection in the loader:

n.loader.components[c.key] = c;

Solution

  • You can utilize the NoFlo ComponentLoader's registerComponent method for this. The trick is to start the NoFlo Network in delayed mode by passing it true as the third parameter. This way it won't start execution immediately, and you can first register your components to it.

    // Create NoFlo network in delayed mode (see the third param in the end)
    noflo.createNetwork(g, function(n) {
    
      // Register the custom components
      components.forEach (function (component) {
        n.loader.registerComponent('myproject', component.key, {
          getComponent: function () { return component; }
        });
      });
    
      // Once the components have been registered we can wire up and start it
      n.connect(function () {
        n.start();
      });
    
    }, true);
    

    The other option would be to register a custom ComponentLoader in your project. That way you wouldn't need to do anything special when starting networks.

    See for example how this is done in noflo-polymer (manifest, custom loader) on browser or MicroFlo (manifest, custom loader) on Node.js.

    Custom component loaders have been supported since NoFlo 0.5.1.