title: upload image and display it with React and python
body: <p>hello i want to upload image profile to my localhost(localhost/react/uploads/) folder from app and display it and, also saving the path into mysql.</p>
  <p>so far, by using postman, i was able to save the path in mysql and send the the image to folder uploads inside the backend</p>
  <p>my problem is that when i run the app (expo-cli) and i add the image to the profile it doesn't send the image, but  when i use postman to test the api it works, and the path of the file will be saved in mysql.  my other problem is that when i use the postman to test api it will save the path of the file but it will upload the image in the directory folder(uploads) of the app. i want a way to upload the image to the localhost server or host like loaclhost/react/uploads.</p>
  <p>app.py</p>
  <pre><code>UPLOAD_FOLDER = 'uploads'
  app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
  
  db = SQLAlchemy(app)
  ma = Marshmallow(app)
  
  
  class User2(db.Model):
      id = db.Column(db.Integer, primary_key=True)
      usernm = db.Column(db.String(255), unique=True)
      password = db.Column(db.String(255))
      email = db.Column(db.String(255))
      phone = db.Column(db.String(255))
      createdAt = db.Column(db.DateTime, default=datetime.datetime.now)
      updatedAt = db.Column(db.DateTime, default=datetime.datetime.now)
      public_id = db.Column(db.String(50), unique=True)
      pic_profile = db.Column(db.String(255))
      pathname = db.Column(db.String(50))
  
      def __repr__(self):
          return f&quot;&lt;User2 {self.usernm}&gt;&quot;
  
      def save(self):
          db.session.add(self)
          db.session.commit()   
  
  
  
      @app.route('/upload', methods=['POST'])
      def upload():
          try:
      
              if 'file' not in request.files:
                  return sennd.badRequest([], 'File tidak tersedia')
      
              file = request.files['file']
      
              if file.filename == '':
                  return sennd.badRequest([], 'File tidak tersedia')
              if file and uploadconfig.allowed_file(file.filename):
                  uid = uuid.uuid4()
                  filename = secure_filename(file.filename)
                  renamefile = str(uuid.uuid4()) + &quot;_&quot; + filename
      
                  file.save(os.path.join(app.config['UPLOAD_FOLDER'], renamefile))
      
                  uploads = User2(pic_profile=renamefile)
                  db.session.add(uploads)
                  db.session.commit()
      
                  return sennd.success(
                      {
                          'pic_profile': renamefile,
                      },
                      &quot;Sukses mengupload file&quot;
                  )
              else:
                  return sennd.badRequest([], 'File tidak diizinkan')
      
          except Exception as e:
              print(e)
      
      
      @auth_ns.route('/signup')
      class SignUp(Resource):
          @auth_ns.expect(signup_model)
          def post(self):
              data = request.get_json()
      
              usernm = data.get('usernm')
      
              db_user = User2.query.filter_by(usernm=usernm).first()
      
              if db_user is not None:
                  return jsonify({&quot;message&quot;: f&quot;User with username {usernm} already exists&quot;})
      
              new_user = User2(
                  public_id=str(uuid.uuid4(
                  )),
                  usernm=data.get('usernm'),
                  email=data.get('email'),
                  password=generate_password_hash(data.get('password')),
                  phone=data.get('phone'),
      
      
      
      
      
              )
      
              new_user.save()
      
              return make_response(jsonify({&quot;message&quot;: &quot;User created successfuly&quot;}), 201)
  </code></pre>
  <p>sennd.py</p>
  <pre><code>from flask import jsonify, make_response
  
  
  def success(values, message):
      res = {
          'data': values,
          'message': message
      }
  
      return make_response(jsonify(res)), 200
  
  
  def badRequest(values, message):
      res = {
          'data': values,
          'message': message
      }
  
      return make_response(jsonify(res)), 400
  </code></pre>
  <p>uploadconfig</p>
  <pre><code>ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'pdf'])
  
  
  def allowed_file(filename):
      return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
  </code></pre>
  <p>signup.js</p>
  <pre><code>import React, { useState, useContext } from &quot;react&quot;;
  import { View, ScrollView, Image, TouchableOpacity } from &quot;react-native&quot;;
  import Text from &quot;@kaloraat/react-native-text&quot;;
  import UserInput from &quot;../components/auth/UserInput&quot;;
  import SubmitButton from &quot;../components/auth/SubmitButton&quot;;
  import axios from &quot;axios&quot;;
  import CircleLogo from &quot;../components/auth/CircleLogo&quot;;
  import { KeyboardAwareScrollView } from &quot;react-native-keyboard-aware-scroll-view&quot;;
  import { AuthContext } from &quot;../context/auth&quot;;
  import AsyncStorage from &quot;@react-native-async-storage/async-storage&quot;;
  import FontAwesome5 from &quot;react-native-vector-icons/FontAwesome5&quot;;
  import * as ImagePicker from &quot;expo-image-picker&quot;;
  
  
  
  const Signup = ({ navigation }) =&gt; {
    const [uploadImage, setUploadImage] = useState(&quot;&quot;);
    const [usernm, setName] = useState(&quot;noura&quot;);
    const [email, setEmail] = useState(&quot;noura@gmail.com&quot;);
    const [password, setPassword] = useState(&quot;nooe&quot;);
    const [phone, setphone] = useState(&quot;1231&quot;);
    const [loading, setLoading] = useState(false);
    const [state, setState] = useContext(AuthContext);
    const [pic_profile, setImage] = useState({ url: &quot;&quot;, public_id: &quot;&quot; });
  
  
    // console.log(&quot;NAVIGATION -&gt; &quot;, navigation);
  
    const handleSubmit = async () =&gt; {
      setLoading(true);
      if (usernm!=&quot;&quot; &amp;&amp; password!=&quot;&quot; &amp;&amp; email!=&quot;&quot; &amp;&amp; phone!=&quot;&quot;  ) {
       await fetch(&quot;http://127.20.10.6:5000/auth/signup&quot;, {
          method: &quot;POST&quot;,
          headers: {
            'Accept': 'application/json',
            'Content-type': 'application/json'
          },
          body: JSON.stringify({usernm:usernm, password:password, email:email, phone:phone})
         }) .then(response =&gt;response.json())
         .then(resData =&gt; {
           if(resData.message == &quot;User created successfuly&quot;) {
           setLoading(false);
           alert(resData.message);
           navigation.navigate(&quot;Home&quot;);
           setState(data);
           // save response in async storage
            AsyncStorage.setItem(&quot;@auth&quot;, JSON.stringify(data));
           } else {
             setLoading(false);
             alert(resData.message);
           }
         })
    } else{
      alert(&quot;All fields are required&quot;);
      setLoading(false);
    }
    setLoading(false);
  }
  
  const handleUpload = async (e) =&gt; {
    let permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();
    // console.log(permissionResult);
    // return;
    if (permissionResult.granted === false) {
      alert(&quot;Camera access is required&quot;);
      return;
    }
    // get image from image
    let pickerResult = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      aspect: [4, 3],
      base64: true,
    });
    // console.log(&quot;PICKER RESULT =&gt; &quot;, pickerResult);
    if (pickerResult.cancelled === true) {
      return;
    }
    // save to state for preview
    let base64Image = `data:image/jpg;base64,${pickerResult.base64}`;
    setUploadImage(base64Image);
    // send to backend for uploading to cloudinary
  
   setLoading(false);
   e.preventDefault();
      let path = await uploadFileHandler(uploadFile);
      dispatch(createItem({
         ...data,
         pic_profile: path, // idk if this is the correct property name on the data
      }, headers));
  
  }
  const uploadFileHandler = async (file) =&gt; {
    const formData = new FormData();
    formData.append('image', file);
    setLoading(true);
    try {
      const config = {
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      };
      const fileURL = await fetch('http://127.20.10.6:5000/upload', formData, config);
      setLoading(false);
      return fileURL.data; //this is the path of the uploaded file
    } catch (error) {
      console.error(error);
      setLoading(false);
    }
  };
  
  //TODO: Submit handler
    return (
      &lt;KeyboardAwareScrollView
        contentCotainerStyle={{
          flex: 1,
          justifyContent: &quot;center&quot;,
        }}
      &gt;
        &lt;View style={{ marginVertical: 100 }}&gt;
        &lt;CircleLogo&gt;
            {pic_profile &amp;&amp; pic_profile.url ? (
              &lt;Image
                source={{ uri: pic_profile.url }}
                style={{
                  width: 190,
                  height: 190,
                  borderRadius: 100,
                  marginVertical: 20,
                }}
              /&gt;
            ) : uploadImage ? (
              &lt;Image
                source={{ uri: uploadImage }}
                style={{
                  width: 190,
                  height: 190,
                  borderRadius: 100,
                  marginVertical: 20,
                }}
              /&gt;
            ) : (
              &lt;TouchableOpacity onPress={() =&gt; handleUpload()}&gt;
                &lt;FontAwesome5 name=&quot;camera&quot; size={25} color=&quot;orange&quot; /&gt;
              &lt;/TouchableOpacity&gt;
            )}
          &lt;/CircleLogo&gt;
  
          {pic_profile &amp;&amp; pic_profile.url ? (
            &lt;TouchableOpacity onPress={() =&gt; handleUpload()}&gt;
              &lt;FontAwesome5
                name=&quot;camera&quot;
                size={25}
                color=&quot;orange&quot;
                style={{ maringTop: -5, marginBottom: 10, alignSelf: &quot;center&quot; }}
              /&gt;
            &lt;/TouchableOpacity&gt;
          ) : (
            &lt;&gt;&lt;/&gt;
          )}
          &lt;Text title center&gt;
            Sign Up
          &lt;/Text&gt;
  
          &lt;UserInput
            name=&quot;NAME&quot;
            value={usernm}
            setValue={setName}
            autoCapitalize=&quot;words&quot;
            autoCorrect={false}
          /&gt;
          &lt;UserInput
            name=&quot;EMAIL&quot;
            value={email}
            setValue={setEmail}
            autoCompleteType=&quot;email&quot;
            keyboardType=&quot;email-address&quot;
          /&gt;
          &lt;UserInput
            name=&quot;PASSWORD&quot;
            value={password}
            setValue={setPassword}
            secureTextEntry={true}
            autoComplteType=&quot;password&quot;
          /&gt;
           &lt;UserInput
            name=&quot;PHONE&quot;
            value={phone}
            setValue={setphone}
            secureTextEntry={true}
            autoComplteType=&quot;phone&quot;
          /&gt;
  
  
          &lt;SubmitButton
            title=&quot;Sign Up&quot;
            handleSubmit={handleSubmit}
            loading={loading}
          /&gt;
  
          &lt;Text small center&gt;
            Already Joined?{&quot; &quot;}
            &lt;Text onPress={() =&gt; navigation.navigate(&quot;Signin&quot;)} color=&quot;#ff2222&quot;&gt;
              Sign In
            &lt;/Text&gt;
          &lt;/Text&gt;
        &lt;/View&gt;
      &lt;/KeyboardAwareScrollView&gt;
    );
  };
  
  export default Signup;
  </code></pre>