1

I'm trying to upload a image from react native expo-image to my ColdFusion server.

My react native component:

import * as ImagePicker from 'expo-image-picker';
...
_pickImage = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
    });

    if (!result.cancelled) {
      this.setState({ image: result.uri });
    }
  };

  _takePicture = async () => {
    const result = await ImagePicker.launchCameraAsync({
      allowsEditing: true,
      aspect: [4, 3],
    });

    if (!result.cancelled) {
      this.setState({ image: result.uri });
    }
  }

...

<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
    <Button onPress={this._pickImage}>
        <Text>Select a Image</Text>
    </Button>
    <Button onPress={this._takePicture}>
        <Text>Take a Picture</Text>
    </Button>
</View>
...

Then, in my action file I send to my .cfc file using axis

export const addWO = (obj) => {
  return (dispatch) => {
    const formData = new FormData();
    formData.append('file', obj.image);
    console.log('>> formData >> ', formData);
    axios.post('http://myServer/MyCFC.cfc?method=myMethod',
          formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }
      ).then 
     ...

In my .cfc file, I try to upload using fileUpload (CFScript):

destination = expandPath("./myFolder/");
if(!directoryExists(destination)){
    directoryCreate(destination);
}
fileUpload(destination, arguments.File, "*", "MakeUnique" );

When I run it, the arguments.File contains:

file:///Users/myUser/Library/Developer/CoreSimulator/Devices/AE9B608B-3FFB-4C72-8971-C14D56E978F7/data/Containers/Data/Application/116E6C9C-B7EA-429B-8C4A-D89AF777BAA6/Library/Caches/ExponentExperienceData/%2540anonymous%252FiRentApp-5f186599-13ec-4736-b728-f84288e5a0cc/ImagePicker/3762AF23-5F01-453D-B257-E1FB25832994.jpg

However, the ColdFusion .cfc returns the error:

The form field file:///Users/myUser/Library/Developer/CoreSimulator/Devices/AE9B608B-3FFB-4C72-8971-C14D56E978F7/data/Containers/Data/Application/116E6C9C-B7EA-429B-8C4A-D89AF777BAA6/Library/Caches/ExponentExperienceData/%2540anonymous%252FiRentApp-5f186599-13ec-4736-b728-f84288e5a0cc/ImagePicker/3762AF23-5F01-453D-B257-E1FB25832994.jpg did not contain a file.

How can I upload a file from expo-image to the server?

Thank you.

I found the problem. We need to add the uri to the forData:

const imgName = 'myIMG.png';
formData.append('test', { uri: obj.image, name: imgName });
``
myTest532 myTest532
  • 2,091
  • 3
  • 35
  • 78
  • First thing I see wrong is that your http method should be ‘post’, not ‘test’. – Redtopia Sep 04 '19 at 22:20
  • In addition to using `post`, a search on "axios upload file" found [this thread](https://stackoverflow.com/questions/43013858/how-to-post-a-file-from-a-form-with-axios) which says to add the file to a `formData` object - and set the `Content-Type` to `multipart/form-data`. – SOS Sep 05 '19 at 06:32
  • @Redtopia the http type is 'get'. 'test' is the method – myTest532 myTest532 Sep 05 '19 at 13:59
  • @Ageax I updated to use Post and Content-Type (edited the code in the post), but it returns "The form field file did not contain a file" – myTest532 myTest532 Sep 05 '19 at 14:20
  • @myTest532myTest532 - The 2nd argument is supposed to be the *name* of the form field. In your case the name is "File". Though I'd suggest using a different field name, as "file" might be problematic in some contexts. Once you get it working, make the MimeType more restrictive (i.e. don't accept all `*`) – SOS Sep 05 '19 at 16:56
  • @Ageax the issue is that ColdFusion is saying that "The form field file did not contain a file" not that the argument does not exists. – myTest532 myTest532 Sep 05 '19 at 19:41
  • @myTest532myTest532 - I didn't say the argument doesn't exist, but that it contains the wrong thing. The error is saying "The form field *[big long string that's NOT actually a form field name]* doesn't contain a file". It's expecting the *name* of the form field, i.e. "file" but the code is passing in a path instead. – SOS Sep 05 '19 at 19:48
  • @Ageax I don't understand. I changed the parameter name to 'test' and I did a dump in the arguments it contains DATA: unffined and TEST: file://.... What should I pass to fileUpload? – myTest532 myTest532 Sep 05 '19 at 20:39
  • @myTest532myTest532 - Hm... what do you see when you dump `#form#`? FileUpload looks for the name of a field in the `form` scope. – SOS Sep 05 '19 at 20:43
  • @Ageax #form# is showing same data as in arguments. fileUpload(destination, form.test, "*", "MakeUnique" ) returns same error: The form field did not contain a file – myTest532 myTest532 Sep 05 '19 at 20:59
  • @myTest532myTest532 - Not quite. Using `form.test` passes in the field's value, ie The path *"file:///Users/myUser/Library/...."*. The function wants the NAME of the form field in quotes (and don't use pound signs). ie `FileUpload(destination, "test", "*", "MakeUnique")`. – SOS Sep 05 '19 at 21:12
  • @Ageax Thanks. I understand what you mean, but now it is returning: "The form field test did not contain a file" – myTest532 myTest532 Sep 05 '19 at 21:20
  • I haven't used axios, but it seems like the code isn't passing something correctly. If the file upload was successful, I'd expect to see the usual CF temp file path, i.e. neoxxxxx.tmp. Maybe take another look at the github examples https://github.com/expo/image-upload-example/ – SOS Sep 05 '19 at 22:10
  • expo-image is generating file:///Users/myUser/Library/Developer/CoreSimulator/Devices/long-text.jpg, not a .tmp file – myTest532 myTest532 Sep 09 '19 at 14:43
  • I believe the .tmp file is generated when we use input type="file" in a ColdFusion server – myTest532 myTest532 Sep 09 '19 at 15:09
  • FileUpload can only operate on a server side file path, i.e. .tmp file. This looks like a client side path, ie file:///Users/myUser/Library/Developer/CoreSimulator/Devices/long-text.jpg. Where is axios uploading the actual content of that file? Also, could you do a cfdump of GetHttpRequestData() in the CFC? – SOS Sep 10 '19 at 15:38
  • 1
    @Ageax thank you for all your hep. We forgot to add the uri to the FormData (I posted the solution). After including the URI, ColdFusion receives the file with the extension .tmp – myTest532 myTest532 Sep 10 '19 at 16:31
  • @myTest532myTest532 - Ahh, glad you figured it out! You should post that + working `FileUpload(..)` code as an "answer", so it's more visible. Plus people can up vote it too. (It's okay to answer your own question on S.O.) – SOS Sep 10 '19 at 17:11

1 Answers1

2

I figured out the solution. We need to add the URI to the FormData. I also include a name

const formData = new FormData();
const imgName = 'myIMG.png';
formData.append('test', { uri: obj.image, name: imgName });
axios.post('http://myServer/MyCFC?method=myMethod',
     formData, {
         headers: {
            'Content-Type': 'multipart/form-data'
         }
     }
).then
...

... and changed the CFC upload code to:

fileUpload(destination, "test", "*", "MakeUnique" ); 
SOS
  • 6,430
  • 2
  • 11
  • 29
myTest532 myTest532
  • 2,091
  • 3
  • 35
  • 78