Attach simple text file into issue

Hi,

I want to make an issue attachment as API rest say, so first tried to create a simple text file and then fetch it to attach method, but I had this error:

TypeError: function FileHandle(vol, fd) {
this.vol = vol;
this.fd = fd;
} could not be cloned.

What is wrong?

Here is a sample code:

//generating text file
var data = "First,Second"
data += "\r\nThird,Forth"
require("fs").writeFileSync("FILE.CSV", data)

 const filePath = 'FILE.CSV';
 const stats = require("fs").statSync(filePath);
 const fileSizeInBytes = stats.size;
 const fileStream = require("fs").createReadStream(filePath);



form.append('file', fileStream, {knownLength: fileSizeInBytes});

 const response = await api.asApp().requestJira(route`/rest/api/2/issue/{issueIdOrKey}/attachments`, {
     method: 'POST',
     body: form,
     headers: {
         'Accept': 'application/json',
         'X-Atlassian-Token': 'no-check'
     }
 });

 console.log(`Response: ${response.status} ${response.statusText}`);
 console.log(await response.json());

Thanks

Hi @Xavifernandez, thank you for reaching out.
I think the problem is that fs.createReadStream returns FileHandle object. I did similar exercise but instead using fs I took a file from <input type="file" ... /> and it worked as expected (I believe in my case, file object is not a stream but string that represents the path to the selected file). Please give it a try (either use input or change parameter from fileStream to path).
I assume there is an issue in our documentation example that we should fix.
https://ecosystem.atlassian.net/browse/FRGE-114?focusedCommentId=690186

Best regards,
Ɓukasz

1 Like

Thanks for reply!!

If I undertand well, the line

form.append('file', fileStream, {knownLength: fileSizeInBytes});

Its ok, but the fileStream object is not valid.

am I rigth?

Also u say using input button, then I assume user must select a file.
But what if im generating programatically a new file and I want to attach the resulting file?

Thaks again.

Hi @Xavifernandez,

What I meant is to replace fileStream that is currently a FileHandle object with string representing the path to the file. In my case, when I’m using input type="file", the value is: <input type="file"> - HTML: HyperText Markup Language | MDN

But what if im generating programatically a new file and I want to attach the resulting file?

It’s ok, what I think will work is changing fileStream to path to the file (there is no need to force user to select a file). Please give it a try and let me know if it helps.

Best regards,
Ɓukasz

Ok,

I replaced filestream for filepath:

//generating text file
var data = "First,Second"
data += "\r\nThird,Forth"
require("fs").writeFileSync("FILE.CSV", data)

 const filePath = 'FILE.CSV';
 
form.append("file", filePath);

But I got the error:

Something went wrong
Trace ID: d493f9632c1db9fd
There was an error invoking the function - function () { [native code] } could not be cloned.

TypeError: function () { [native code] } could not be cloned.
    at s.wrapValue (bootstrap.js:1:2144)
    at s.wrap (bootstrap.js:1:1504)
    at bootstrap.js:1:2270
    at Array.map (<anonymous>)
    at s.wrapArray (bootstrap.js:1:2257)
    at s.wrap (bootstrap.js:1:1574)
    at bootstrap.js:1:797
    at Array.map (<anonymous>)
    at s.applyIgnored (bootstrap.js:1:784)
    at s.callIgnored (bootstrap.js:1:498)

Hi @Xavifernandez,

I did this exercise myself and below code works for me:

const file = new File(
      ["Test content"], 
      "file.csv",                     
      { type: "text/plain" }
    );

const form = new FormData();
form.append('file', file, {knownLength: file.size});

const response = await requestJira('/rest/api/2/issue/TEST-2/attachments', {
   method: 'POST',
   body: form,
   headers: {
       'Accept': 'application/json',
       'X-Atlassian-Token': 'no-check'
   }
});

console.log(`Response: ${response.status} ${response.statusText}`);
console.log(await response.json());

Please give it a try and let me know if it works for you as well. It’s just an idea how to upload the file (File object representing file is required to be passed in the form).

I hope it helps. Best regards,
Ɓukasz

Thanks again Ɓukasz,

May I import some module before try ur code?
I got this error

ReferenceError: File is not defined
    at Object.onSubmit2 [as onSubmit] (webpack://forge-ui-starter/src/index.jsx:88)
    at /tmp/tunnel7NqP35oIJ97cV/index.js:1520:60
    at asyncMap (webpack://forge-ui-starter/node_modules/@forge/ui/out/reconcile.js:12)
    at /tmp/tunnel7NqP35oIJ97cV/index.js:1523:35
    at asyncMap (webpack://forge-ui-starter/node_modules/@forge/ui/out/reconcile.js:12)
    at /tmp/tunnel7NqP35oIJ97cV/index.js:1523:35
    at asyncMap (webpack://forge-ui-starter/node_modules/@forge/ui/out/reconcile.js:12)
    at /tmp/tunnel7NqP35oIJ97cV/index.js:1523:35
    at asyncMap (webpack://forge-ui-starter/node_modules/@forge/ui/out/reconcile.js:12)
    at async /tmp/tunnel7NqP35oIJ97cV/index.js:1523:29

Hi @Xavifernandez,

I forgot to mention that I was using Custom UI. I can see that you use UI Kit and I think, it can be the reason of the error, since UI Kit is rather limited and is designed for Forge apps with simpler use cases (utilising built-in Atlassian components).
Could you try the same with Custom UI or it isn’t an option in your case?

Best regards,
Ɓukasz

Have you solved the problem?

hiI also encountered this problem. I use custom UI, but Node does not support new File(). Is there any other way to do this?

Hi @liumulin,
Unfortunately it seems that there still is a problem. Please take a look at this ticket: [FRGE-114] - Ecosystem Jira - I forwarded the question to the responsible team and I hope they can provide further help.

Best regards,
Ɓukasz