How to retrieve the base64 value and the mimetype of a variable of type "File" in a JS external worker?

Hello,

I have a process with the following process variables:

Additionally, there is a JS external worker. In this worker, I have a const age = task.variables.get(“age”); statement to retrieve the value of the variable “age”. This works as expected.

The question is, how could I retrieve the base64 value of the “document1” variable and its mimetype???

When I try to have const document1 = task.variables.get(“document1”); and then print in the console the document1 variable, I see something like this:

File {
  load: [Function: bound load] AsyncFunction,
  createTypedValue: [Function: bound createTypedValue],
  __readFile: [Function: readFile],
  remotePath: '/execution/72fd9114-7186-11ed-951e-d850e649bc61/localVariables/document1/data',
  engineService: EngineService {
    workerId: 'some-random-id',
    baseUrl: 'http://localhost:8080/engine-rest',
    interceptors: undefined,
    request: [Function: bound request] AsyncFunction,
    post: [Function: bound post],
    get: [Function: bound get],
    fetchAndLock: [Function: bound fetchAndLock],
    complete: [Function: bound complete],
    handleFailure: [Function: bound handleFailure],
    lock: [Function: bound lock]
  },
  encoding: 'UTF-8',
  filename: 'test.png',
  content: ''
}

Hello,

could anyone help me with this?

Your help would be much appreciated, as I don’t know how to continue and solve my issue.

Cheers,
Smith.

Hi @smith_Johnson,

If you want to use an external Task Worker with non-primitive data types, I recommend serializing and deserializing the objects explicitly. This way, you have full control over their format.
The documentation has an article about data formats, which may help you:

However, the JS-Client provides an interface for handling files:

Calling the load function loads the file from the remote path. Once the call completed, content should contain the base64 value of the file.

For further reference, check out file.js and file.test.js

I hope this helps.

1 Like

Hi @StephanHaarmann ,

appreciate your time to respond on my query.

May I ask you if you can provide some more guidance on the following?

I tried to use the remote path, but I don’t know if I missed something:

console.log("External JS worker started!!!");

const { Client, logger, File } = require("camunda-external-task-client-js");
const { Variables } = require("camunda-external-task-client-js");

const config = { baseUrl: "http://localhost:8080/engine-rest", use: logger };

const client = new Client(config);

client.subscribe("APIcall", async function({ task, taskService }) {

    const id=task.businessKey;
    const fullname= task.variables.get("fullname");
    const email = task.variables.get("email");
    const document1 = task.variables.get("document1");

    console.log(id+" "+fullname+" "+email);
    console.log(document1.remotePath);

    const file = await new File({ remotePath: document1.remotePath }).load();
    console.log("File content is: "+file.content);

    await taskService.complete(task, processVariables);
});

I see the following in the console, but the file content is never printed out.

External JS worker started!!!
✓ subscribed to topic APIcall
TESTABC Smith Johnson smithtest@gmail.com
/execution/c51e12f8-754c-11ed-9db5-d850e649bc61/localVariables/document1/data

Are the following statements correct? Apparently, I miss something, but I don’t know what :frowning:

const { Client, logger, File } = require("camunda-external-task-client-js");
const document1 = task.variables.get("document1"); // the name of the process variable is "document1"
const file = await new File({ remotePath: document1.remotePath }).load();

Thank you once again for your time and help,
Smith.

@StephanHaarmann

I updated my code to this, but I still miss something, since it does not work.

    const document1 = task.variables.get("document1"); //process variable "document1" of type File
    const remotePath=document1.remotePath; //e.g., /execution/0b17d518-7553-11ed-9db5-d850e649bc61/localVariables/document1/data
    const engineService = {
        get: jest.fn().mockImplementation(() => Promise.resolve(value)),
    };
    const file2 = await new File({remotePath,engineService}).load();
    console.log("file2: "+file2.filename);

I think the “engineService” parameter is not correct.

Any ideas are welcomed

Unfortunately, I’m not very familiar with the Javascript client.
Is document1 a File, as described in your first post?
If so, what happens, if you call document1.load()?

1 Like

This was the solution :slight_smile:

Thank you very very much :pray: :pray:

Much appreciated!!