0

I'm trying to make an app that takes a picture and then returns the list of objects detected on that image. the code below is the whole code i'm using. i've changed the url of the api to 'insert api url here' just incase some troll find this post and spams the api with requests but i've made sure that the api url i'm using the correct one as i've tested it on postman and just copy pasted the api url.

import React, { useState, useEffect, useRef } from "react";
import { Text, View, StyleSheet, TouchableOpacity, Image } from "react-native";
import Constants from "expo-constants";
import { Camera, CameraType } from "expo-camera";
import * as MediaLibrary from "expo-media-library";
import { MaterialIcons } from "@expo/vector-icons";
import Button from "./src/components/Button";
import axios from "axios";
export default function App() {
  const [hasCameraPermission, setHasCameraPermission] = useState(null);
  const [image, setImage] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);
  const [flash, setFlash] = useState(Camera.Constants.FlashMode.off);
  const cameraRef = useRef(null);

  useEffect(() => {
    (async () => {
      MediaLibrary.requestPermissionsAsync();
      const cameraStatus = await Camera.requestCameraPermissionsAsync();
      setHasCameraPermission(cameraStatus.status === "granted");
    })();
  }, []);

  const takePicture = async () => {
    if (cameraRef) {
      try {
        const data = await cameraRef.current.takePictureAsync();
        console.log(data);
        setImage(data.uri);
      } catch (error) {
        console.log(error);
      }
    }
  };

  const savePicture = async () => {
    if (image) {
      try {
        const asset = await MediaLibrary.createAssetAsync(image);

        axios
          .post("insert api url here", {
            Imagee: image,
          })
          .then((response) => {
            console.log(response);
          })
          .catch((error) => {
            console.log(error);
          });

        alert("done");
        setImage(null);
        console.log("saved successfully");
      } catch (error) {
        console.log(error);
      }
    }
  };

  if (hasCameraPermission === false) {
    return <Text>No access to camera</Text>;
  }

  return (
    <View style={styles.container}>
      {!image ? (
        <Camera
          style={styles.camera}
          type={type}
          ref={cameraRef}
          flashMode={flash}
        >
          <View
            style={{
              flexDirection: "row",
              justifyContent: "space-between",
              paddingHorizontal: 30,
            }}
          >
            <Button
              title=""
              icon="retweet"
              onPress={() => {
                setType(
                  type === CameraType.back ? CameraType.front : CameraType.back
                );
              }}
            />
            <Button
              onPress={() =>
                setFlash(
                  flash === Camera.Constants.FlashMode.off
                    ? Camera.Constants.FlashMode.on
                    : Camera.Constants.FlashMode.off
                )
              }
              icon="flash"
              color={flash === Camera.Constants.FlashMode.off ? "gray" : "#fff"}
            />
          </View>
        </Camera>
      ) : (
        <Image source={{ uri: image }} style={styles.camera} />
      )}

      <View style={styles.controls}>
        {image ? (
          <View
            style={{
              flexDirection: "row",
              justifyContent: "space-between",
              paddingHorizontal: 50,
            }}
          >
            <Button
              title="Re-take"
              onPress={() => setImage(null)}
              icon="retweet"
            />

            <Button
              type="submit"
              title="Save"
              onPress={savePicture}
              icon="check"
            />
          </View>
        ) : (
          <Button title="Take a picture" onPress={takePicture} icon="camera" />
        )}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    paddingTop: Constants.statusBarHeight,
    backgroundColor: "#000",
    padding: 8,
  },
  controls: {
    flex: 0.5,
  },
  button: {
    height: 40,
    borderRadius: 6,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
  },
  text: {
    fontWeight: "bold",
    fontSize: 16,
    color: "#E9730F",
    marginLeft: 10,
  },
  camera: {
    flex: 5,
    borderRadius: 20,
  },
  topControls: {
    flex: 1,
  },
});

The part where it makes a post request the code snippet below. so what i'm trying to do is store the uri of the image using state and then sending that uri to the api using axios. i've made sure that the api is working on postman before testing it on my react native code but somehow i keep getting

[AxiosError: Request failed with status code 400]

I searched online as to what error 400 means and it says that it is an error caused by an invalid request which i find weird as the url is correct and i've done what every blog post or documentation axios has on post request has shown me.

const savePicture = async () => {
  if (image) {
    try {
      const asset = await MediaLibrary.createAssetAsync(image);

      axios
        .post("insert api url here", {
          Imagee: image,
        })
        .then((response) => {
          console.log(response);
        })
        .catch((error) => {
          console.log(error);
        });

      alert("done");
      setImage(null);
      console.log("saved successfully");
    } catch (error) {
      console.log(error);
    }
  }
};
Phil
  • 157,677
  • 23
  • 242
  • 245
bam mazino
  • 21
  • 2
  • Can you show an example screenshot from Postman where the API call is working (redact whatever you feel necessary)? It looks like your `image` state variable is set to a string (the URI), is that what the API expects? You're sending it a JSON payload with an `Imagee` property. Is that spelled correctly? – Phil Jul 01 '22 at 02:13
  • here's the image of the postman api working. https://imgur.com/xraoVvQ – bam mazino Jul 01 '22 at 03:13
  • i used the Imagee property as before i thought that the Image tag was conflicting with the Image property i am using for the api and so i renamed it – bam mazino Jul 01 '22 at 03:13
  • Right, so you're actually sending a `multipart/form-data` request with Postman that contains an actual binary image file. A URI string is not the same thing – Phil Jul 01 '22 at 03:14
  • how would i convert the uri from a string into a img file i can send to the api? – bam mazino Jul 01 '22 at 03:14
  • Does this answer your question? [Expo Camera Photo Upload To Firebase Storage is undefined - React Native](https://stackoverflow.com/questions/71280708/expo-camera-photo-upload-to-firebase-storage-is-undefined-react-native). Otherwise, you could get the base64 data and [convert that to a file blob](https://stackoverflow.com/a/70794852/283366) – Phil Jul 01 '22 at 03:16

0 Answers0