Skip to main content

I'm working on an LucidChart extension that needs to fetch CSV data from a web API endpoint and create a TableBlock with that data on a PageProxy. The approach I took was:

1. Fetch CSV data using my Api Service
2. Return this CSV data through a DataConnectorAction
3. Use the returned data to populate a TableBlock

Here's my data connector action code:

```typescript
// actions/getActivityUtilizationAction.ts
import { DataConnectorAsynchronousAction } from 'lucid-extension-sdk';
import { createLucidApiService } from '@quodsi/shared';
import { getConfig } from '../config';

export const getActivityUtilizationAction: (action: DataConnectorAsynchronousAction) => Promise<{ status: number } & { text: string }> = async (
    action,
) => {
    try {
        const data = action.data as { documentId: string, userId: string };
        const { documentId, userId } = data;
        const authToken = action.context.userCredential;

        const config = getConfig();
        const baseUrl = config.apiBaseUrl;
        const lucidApiService = createLucidApiService(baseUrl);

        // Get the CSV blob from our API
        const csvBlob = await lucidApiService.getActivityUtilization(documentId, userId);
        const csvText = await csvBlob.text();

        return { 
            status: 200,
            text: csvText
        };
    } catch (error) {
        console.error("getActivityUtilizationAction] Error:", error);
        return { 
            status: 500,
            text: error instanceof Error ? error.message : 'Unknown error occurred'
        };
    }
};
```

This action is called from my ModelPanel extends Panel when a user requests to create a new page with the CSV data:

```typescript
// Within ModelPanel.ts
private async handleOutputCreatePage(data: { pageName: string }): Promise<void> {
    try {
        const document = new DocumentProxy(this.client);
        const user = new UserProxy(this.client);
        const docId = document.id;
        const userId = user.id;

        // Create new page
        const page = document.addPage({
            title: data.pageName,
        });

        // Try to get CSV data through the data connector
        const result = await this.client.performDataAction({
            dataConnectorName: 'quodsi_data_connector',
            actionName: 'GetActivityUtilization',
            actionData: { documentId: docId, userId: userId },
            asynchronous: false
        });

        if (result.status !== 200 || !result.text) {
            throw new Error('Failed to fetch CSV data');
        }

        // Parse the CSV and create TableBlock with the data
        const parsedData = await parseCsvBlob(new Blob(rresult.text], { type: 'text/csv' }));
        // ... TableBlock creation code ...
    } catch (error) {
        console.error(' ModelPanel] Error:', error);
    }
}
```

I'm getting TypeScript errors about the response type from the data connector action. Looking at the SDK documentation and types:

```typescript
export type DataActionResponse = {
    'status': number;
} & ({
    'json': unknown;
} | {
    'text': string;
});
```

My question is: What's the correct way to return data from a DataConnectorAction so that it can be accessed in the performDataAction response? I need to get the CSV content from my action to my extension panel so I can create the TableBlock.

Any guidance would be greatly appreciated!

Thanks,

Dan

P.S.  I have reviewed the data-connector-example.  I see its use of “collections” and within the action 

action.client.update.  Is the only way to get data back into the extension from a dataconnector is through collections?

 

 

I am switching my code to use data collections, etc.  I believe that is the correct design and answers this question.


I'm glad you got this figured out! Thank you for contributing to the Lucid for Developers Community - your insights help others with similar issues. Feel free to reach out if anything else comes up! 


Reply