0
votes

After weeks trying to make this works, I wanted to ask for help before I give up.

Node endpoint is working perfectly as request from Postman sends the image and it's stored in the server. See server code below:

const multer = require('../helpers/multer');

const upload = multer(config.imagesUrl);

module.exports = function(app){

    app.post('/species',
        // ...
        upload.single('image'),
        // ...
    );

But I'm not able to make this work from my React Native application. See the app code below.

import * as ImagePicker from 'expo-image-picker';

export default function AddUser({ navigation }) {
    const [user, setUser] = useState(null);

    const pickImage = async () => {
      let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.All,
        allowsEditing: true,
        aspect: [4, 3],
        quality: 1,
      });

      if (!result.cancelled) {
        setUser({'image', result.uri});
      }

    };

    function onSubmit(){

      let formData = new FormData();

      formData.append('name',  user.name);
      formData.append('groupId',  user.group);

      // Infer the type of the image
      if(user.image){
        let fileName = user.image.split('/').pop();
        let match = /\.(\w+)$/.exec(fileName);
        let fileType = match ? `image/${match[1]}` : `image`;
        formData.append('image', {
          uri: Platform.OS === 'android' ? user.image : user.image.replace('file://', ''),
          name: user.name,
          type: fileType,
        });
      }

      axios.post(backend.url + '/user', formData, { 
        headers: {
          Accept: "application/json",
          "Content-Type": "multipart/form-data"
        }
      })
      .then(res => {
        console.log('SUCCESS');
        // ...
      })
      .catch(err => {
        console.log('ERROR');
        // ...  
      });
    }

    return (
        // ...
        { user.image && <Image source={{ uri: user.image }} style={{ width: 200, height: 200 }} /> }
        <Button onPress={pickImage} >Pick an image</Button>
        <Button onPress={onSubmit} >Send</Button>
        //..
    );
}

After submitting the image from the app, no errors are reported. On the server side the var req.file is undefined but see below the req.body console.log.

[Object: null prototype] {
  name: 'Joe',
  groupId: '5e8cdd3b8296523464c7462d',
  image: '[object Object]' }

All the others application calls are running with axios and default credentials/headers are already implemented. I want to avoid to change to rn-fetch-blob or fetch.

Any idea what's missing?

1
you try debugging what you are sending ? in network tab you should check if you are sending it as binary or not. - anthony willis muñoz
@anthonywillismuñoz In the react native debugger network tab I can see the Form Data with the elements inside. Image is 'image: [object Object]'. I don't think it means binary - Nathan Lo Sabe

1 Answers

1
votes

I was not able to make it work. I found the possibility to use base64. This post explains it pretty well. I used body-parser and forgot about form-data and multer!