Alteryx IO Discussions

Customize and extend the power of Alteryx with SDKs, APIs, custom tools, and more.

Custom Tool UI

Deepta
7 - Meteor

Hello! I've been trying to create a custom UI for a tool I'm making using this, as a reference. My issue here is that the UI simply doesn't show up in my configuration tab. when I first load the tool there's a black flash on the tab and then a blank configuration tab stares at me.

 

I tried to add a warning similar to the one in my reference and got an error saying "none_type" has no method len() in it.

 

I've been trying to find other examples of custom tools with UI but there aren't many.

 

I also looked into the ayx_workspace.json and the UI has no path references. could this be a possible issue?

 

Please help me with any resource or suggestions. Thanks in advance.

15 REPLIES 15
JarrodT
Alteryx
Alteryx

@Deepta, can you look at line 108 in your index.tsx file and maybe add a console.log right before that line to see what values are being passed through? It seems that there is something missing from the object being processed by generateData. I think I've come across this in the past when I was trying to reference values that weren't in my default Configuration object, so it would error because it was trying to perform an operation on a missing object, much like the none_type error.

Deepta
7 - Meteor

@JarrodT After looking into it I believe this is what happened. There is a map inside the function generateData whose input is the meta of the previous tool [possibly a table] since there is no tool it maps nothing hence an error pops up. But in "sample filter UI" this is handled in the backend so there are no issues. Image 8-17-23 at 4.25 PM.jpegImage 8-17-23 at 4.24 PM.jpeg

 

I still don't understand why this UI or the UI of "sample filter UI" doesn't appear in the designer. 

JarrodT
Alteryx
Alteryx

Maybe try adding a couple of console.log statements to see what is actually being processed:

 

    // create field name list from metadata
    const generateData = (data) => {
      console.log("generateData",{data});
      return data.map((item) => {
        console.log("generateData - Item", {data});
        item.primary = item.name;
        item.value = item.name;
        return item.name
      });
    };
 
Maybe the map isn't getting the right portion of the object. 
Deepta
7 - Meteor

Image 8-18-23 at 1.46 PM.jpeg

 

Since there is no meta from the previous tool or input nothing is passed into the function and thus map is not called initially. The 'undefined' you see is when I swap to 'no input' after circling back from 'us address' in meta. 'generateData -item is never called since the function doesn't get any data passed into it.

JarrodT
Alteryx
Alteryx

hey @Deepta , sorry for the delay. I have a feeling that the model.Meta object may be handled correctly somewhere. When I used the example script just now, I noticed the meta reference was looking at fields[0][0] but that was empty for me. By changing it to fields[1][0], it seemed to pull the list.

 

 I recently built a tool with 2 inputs and created a handler for the metadata:

 

 // create field name list from metadata

  const generateData = (data, connectionId) => {
    // If the data isn't filled in, then use these default properties.
    console.log("Index - generateData",{data});
    if (JSON.stringify(data)=="{}" || !data) {
      return ([]); //create a simple lookup table for "missing data" value
    } else {
      return data?.fields[connectionId][0].fields.map((item) => {
        item.primary = item.name;
        item.value = item.name;
        console.log("generateData",{item})
        return item.name
    });
  };
  };
 
Then when calling the generateData function in the autocomplete, it looked like this:
                  <Autocomplete
                    id="Autocomplete"
                    options={generateData(model.Meta,1)} // was model.Meta?.fields[0][0].fields
                    renderInput={params => (
                      <TextField
                        {...params}
                        fullWidth
                        id="ac-meta"
                        label="Meta Data"
                        margin="normal"
                        placeholder="Select Column..."
                      />
                    )}
                    onChange={handleResourceEvent("fieldSelect")} // was handleFieldSelect
                    value={model.Configuration.fieldSelect}
                  />
 
the handleResourceEvent was a new function I created to dynamically handle events like field select (because i was using it multiple times):
  // to handle class objects you have to break down the data into a newValue which equals the json object.
  const handleResourceEvent = (key) => (_, newValue) =>{
    const newModel = { ...model };
    newModel.Configuration = {...newModel.Configuration, [key]:newValue};
    handleUpdateModel(newModel);
  };
 
Hopefully, that helps you get your autocomplete element working. Let me know if you have any questions though. 
- Jarrod
Deepta
7 - Meteor

Hey @JarrodT just as you said I had mentioned previously that I understand why "map" is throwing up as an error. This as you said is because I don't have another component attached to this UI since it's trying to read the input metadata. This is handled in the backend and I had sent a link as well showing how I'd handle this. My issue as before is that all this is displayed on dev-harness when I need it to show up on designer. I'll attach how the error is handled below.