kendraio / kendraio-app

Kendraio App
https://app.kendra.io
MIT License
22 stars 6 forks source link

Optimise pipeline of data through workflows #42

Open darrenmothersele opened 5 years ago

darrenmothersele commented 5 years ago

One idea is to replace clone/deep copy of payload data with immutable objects with structural sharing, eg immutable.js

darrenmothersele commented 5 years ago

Another thing to solve as part of this is the firstChange family of issues. Currently we need an "init" block to kick start workflows, and some blocks have omitFirst and skipFirst config options. These should be unnecessary with a cleaner model for how data is passed through workflows.

Separating the execution of workflows from the display would also fix these issues.

darrenmothersele commented 4 years ago

Example workflow (see variable get output)

{
  "title": "Workflow",
  "adapterName": "bandsintown",
  "blocks": [
    {
      "type": "form",
      "jsonSchema": {
        "type": "object",
        "properties": {
          "artistName": {
            "type": "string",
            "title": "Artist name"
          }
        }
      },
      "uiSchema": {}
    },
    {
      "type": "context",
      "contextPath": "appId",
      "contextBlocks": [
        {
          "type": "variable-get",
          "name": "app_id"
        }
      ],
      "blocks": [
        {
          "type": "http",
          "method": "get",
          "endpoint": {
            "protocol": "https:",
            "host": "rest.bandsintown.com",
            "valueGetters": {
              "pathname": "join('', ['/artists/', data.artistName, '/events'])",
              "query": "{ app_id: context.appId }"
            }
          }
        }
      ]
    },
    {
      "type": "debug",
      "open": 1,
      "showContext": false
    },
    {
      "type": "grid",
      "gridOptions": {},
      "columnDefs": [
        {
          "headerName": "venue",
          "field": "venue.name"
        },
        {
          "headerName": "Artists",
          "field": "lineup"
        },
        {
          "headerName": "Address",
          "valueGetter": "join(', ', [venue.city, venue.country])"
        }
      ]
    }
  ]
}
darrenmothersele commented 4 years ago

This needs fixing

  onSubmit(button) {
    // console.log({ button });
    // TODO: refactor (d)
    this.blocks = get(button, 'blocks', []);
    this.models = this.blocks.map(blockDef => get(blockDef, 'defaultValue', {}));
    this.models.push({});
    setTimeout(() => {
      this.zone.run(() => {
        this.models = [clone(this.model)];
      });
    }, 0);
  }

from the submit handler in the actions block. It causes a double execution of the embedded workflow.

darrenmothersele commented 4 years ago

I've added a check for an empty payload object before posting in the http block:


        const isEmptyObject = obj => (obj instanceof Object && Object.keys(obj).length === 0);
        const payload = this.getPayload();
        if (isEmptyObject(payload)) {
          this.isLoading = false;
          this.hasError = true;
          this.errorMessage = `${toUpper(method)} of empty payload prevented in http block`;
          return;
        }

This will be removed when this issue is sorted.