Upload image with React Native

Asked

Viewed 2,114 times

1

I have this code with React Enable that should send an image to my back, but give me an error . The code is as follows

import React, { useState, useEffect } from "react";
import { SafeAreaView, View, ImageBackground, StyleSheet, TouchableOpacity, Image, Text, TextInput } from "react-native";
import background from "../../assets/por_do_sol.jpeg";
import * as ImagePicker from "expo-image-picker";
import api from "../services/api";


export default function RegisterImage() {
  const [preview, setPreview] = useState("");
  const [types, setTypes] = useState(false);
  const [upload, setUpload] = useState(null);
  function handleSelectTypeImage() {
    setTypes(true);
  }

  async function UploadImage() {
    const formData = new FormData();
    formData.append("image", upload);
    console.log(formData)
    const { data } = await api.post("/posts", formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })

    // console.log(data)
  }

  async function handleSelectCamera() {
    setTypes(false);
    const result = await ImagePicker.launchCameraAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
    })
    if (result.error) {
      console.log("Error")
    } else {
      let prefix;
      let ext;
      if (result.fileName) {
        [prefix, ext] = result.fileName;
        ext = ext.toLowerCase() === 'heic' ? 'jpg' : ext;
      } else {
        prefix = new Date().getTime();
        ext = 'jpg'
      }
      const imageUpload = {
        uri: result.uri,
        type: result.type,
        name: `${prefix}.${ext}`
      }
      setUpload(imageUpload);
      setPreview(result.uri);
    }
  }
  async function handleSelectGalery() {
    setTypes(false);
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
    });
    if (result.error) {
      console.log("Error")
    } else {
      let prefix;
      let ext;
      if (result.fileName) {
        [prefix, ext] = result.fileName;
        ext = ext.toLowerCase() === 'heic' ? 'jpg' : ext;
      } else {
        prefix = new Date().getTime();
        ext = 'jpg'
      }
      const imageUpload = {
        uri: result.uri,
        type: result.type,
        name: `${prefix}.${ext}`
      }
      setUpload(imageUpload);
      setPreview(result.uri);
    }
  }

  return (
    <SafeAreaView>
      <ImageBackground source={background} style={styles.back} >

        <View style={{
          marginTop: 100,
          justifyContent: "center",
          alignItems: "center",
          width: 230,
          height: 240,
          borderWidth: preview ? 0 : 1,
          borderStyle: "dashed",
          borderColor: "#fff",
          borderRadius: 7,
        }}>
          <TouchableOpacity
            style={styles.button}
            onPress={() => handleSelectTypeImage()}
          >
            {types && (
              <View style={styles.containerType}>
                <TouchableOpacity onPress={handleSelectGalery} >
                  <Text style={styles.textButton}>Selecionar da galeria</Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={handleSelectCamera}>
                  <Text style={styles.textButton}>Capturar da câmera</Text>
                </TouchableOpacity>
              </View>
            )}
            {preview.length > 0 ? (
              <Image style={styles.image} source={{
                uri: preview
              }} />
            ) :
              (<Text></Text>)}
          </TouchableOpacity>
        </View>
        <Text style={styles.bioLabel}>Selecione uma imagem de perfil</Text>
        <TouchableOpacity style={styles.bioButton}>
          <Text style={styles.Label} onPress={UploadImage}>Avançar</Text>
        </TouchableOpacity>
      </ImageBackground>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  back: {
    height: "100%",
    width: "100%",
    resizeMode: "cover",
    alignItems: "center"
  },
  image: {
    height: "100%",
    width: "100%",
    resizeMode: "cover",
    borderRadius: 7
  },
  containerType: {
    width: 230,
    height: 100,
    backgroundColor: "#fff",
    borderRadius: 5,
    justifyContent: "center",
    alignItems: "center",
    zIndex: 1
  },
  textButton: {
    fontSize: 16,
    fontWeight: "bold",
    color: "#777",
    marginBottom: 8
  },
  button: {
    width: "100%",
    height: "100%",
    justifyContent: "center",
    alignItems: "center"
  },
  camera: {
    height: 30,
    width: 30,
    resizeMode: "cover"
  },

  bioLabel: {
    color: "#fff",
    fontSize: 16,
    textAlign: "center",
    marginTop: 10
  },
  Label: {
    color: "#fff",
    fontSize: 16,
    textAlign: "center",
  },

  bioButton: {
    height: 50,
    width: 300,
    borderWidth: 0.3,
    borderColor: "#fff",
    borderRadius: 5,
    padding: 10,
    justifyContent: "center",
    alignItems: "center",
    marginTop: 20,
    backgroundColor: "#ffffff80"
  }
});

And the same returns me this error

[Unhandled promise rejection: ReferenceError: Can't find variable: data]

Stack trace:
  src/pages/RegisterImage.js:26:4 in UploadImage$
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:30 in invoke
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:44 in tryCatch
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:135:28 in invoke
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:170:17 in <unknown>
  node_modules/promise/setimmediate/core.js:45:7 in tryCallTwo
  node_modules/promise/setimmediate/core.js:200:23 in doResolve
  node_modules/promise/setimmediate/core.js:66:12 in Promise
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:169:27 in callInvokeWithMethodAndArg
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:192:38 in enqueue
  node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:216:8 in async
  src/pages/RegisterImage.js:16:2 in UploadImage
  node_modules/react-native/Libraries/Text/Text.js:237:27 in touchableHandlePress
  node_modules/react-native/Libraries/Components/Touchable/Touchable.js:878:34 in _performSideEffectsForTransition

Can someone give me some strength? I don’t know what else to do

  • const { data } = await api.post(...) - Unhandled promise rejection: ReferenceError: Can't find variable: data. Is this issue being resolved? Debugged to see if this property exists data?

1 answer

1

From what I’ve seen of your example, the image data comes from a state variable, and you can capture the image in two ways, from the image gallery or the camera.

The "date" will only exist if communication with your API is no problem. You need to put a "Try/catch" to better identify the error. Could be an issue in the API access address or route.

Here’s an example of how to send an image to the API, the receive function I think will help you:

import api from "../services/api";
async function enviar_imagem(imagem_recebida){
	try {
		const userAuthToken = "TOKEN_DE_ACESSO_A_API";
		const requestConfigFile = {
		  headers: {
			Authorization: `bearer ${userAuthToken}`,
			"Content-Type": "multipart/form-data"
		  }
		};
		const dataFile = new FormData();
		const fileURL = imagem_recebida.uri;
		const fileName = fileURL.split("/").pop();
		const ext = fileURL.split(".").pop();
		dataFile.append("file", {
		  uri: fileURL, // Caminho da imagem
		  name: fileName,
		  type: "image/" + ext
		});
		const response = await api.post("/salvar_imagem", dataFile, requestConfigFile);
		console.log(response);
		const id_imagem = response.data.file.id;
		console.log(id_imagem);
	} catch (err) {
	   console.log(err);
	} 
}

  • Thanks,the error does not come from api,found that if I take the formData,it sends the request and returns me a reply, but if I add the formData again,it consists of this error

Browser other questions tagged

You are not signed in. Login or sign up in order to post.