0
votes

I need to upload a selection of images that user picked from CameraRoll to the LoopBack Component Storage. The thing is that the component storage is working fine, because I can upload and download the files through Postman. But, when I try to upload from react native to loopback, it always returns "No file content upload" with http status 400.

I read a lot of people talking about it and tried everything and none worked for me.

First, I am taking the images from the CameraRoll and my images array looks like this:

[
  {
    exists: 1,
    file: "assets-library://asset/asset.JPG?id=3FF3C864-3A1A-4E55-9455-B56896DDBF1F&ext=JPG",
    isDirectory: 0,
    md5: "428c2e462a606131428ed4b45c695030",
    modificationTime: 1535592967.3309255,
    size: 153652,
    uri: null
  }
]

In the example above I just selected one image.

I transformed to Blob, then I got:

[
  {
    _data: {
      blobId: "3FF3C864-3A1A-4E55-9455-B56896DDBF1F",
      name: "asset.JPG",
      offset: 0,
      size: 153652,
      type: "image/jpeg"
    }
  }
]

So I tried a lot of things after this, tried to send the blob itself as the request body, tried to append to a form data and send the form data, but it doesn't matter the way I try, I always get the "No file content upload" response.

I also tried the example from Facebook, didn't work: https://github.com/facebook/react-native/blob/master/Libraries/Network/FormData.js#L28

The way I am trying now:

In my view:

  finalizarCadastro = async () => {
    let formData = new FormData();
    let blobs = [];
    for(let i=0;i<this.state.fotos.length;i++){
      let response = await fetch(this.state.fotos[i]);
      let blob = await response.blob();
      blobs.push(blob);
    }
    formData.append("files", blobs);
    this.props.servico.criar(formData);
  }

And the function that send to my server:

criar: (servico) => {
  this.setState({carregando: true});
  axios.post(`${REQUEST_URL}/arquivos/seila/upload`, servico, {headers: {'content-type': 'multipart/form-data'}}).then(() => {
    this.setState({carregando: false});
    this.props.alertWithType("success", "Sucesso", "Arquivo salvo com sucesso");
  }).catch(error => {
    this.setState({carregando: false});
    console.log(error.response);
    this.props.alertWithType("error", "Erro", error.response.data.error.message);
  })
}
1

1 Answers

0
votes

I found the solution. So the problem was actually not the code itself, the problem was sending multiple files at the same time. To fix everything, I did this:

this.state.fotos.forEach((foto, i) => {
  formData.append(`foto${i}`, {
    uri: foto,
    type: "image/jpg",
    name: "foto.jpg"
  });
})
this.props.servico.criar(formData);

And my function that sends the request to the server:

criar: (servico) => {
  this.setState({carregando: true});
  axios.post(`${REQUEST_URL}/arquivos/seila/upload`, servico).then((response) => {
    this.setState({carregando: false});
    this.props.alertWithType("success", "Sucesso", "Arquivo salvo com sucesso");
  }).catch(error => {
    this.setState({carregando: false});
    this.props.alertWithType("error", "Erro", error.response.data.error.message);
  })
},

So you don't need to set the Content-Type header to multipart/form-data and don't need to transform the images to blob, actually you just need the uri of each one, and I think the type and name attributes are opcional.