0

I'm trying to upload the image from the React to the flask backend along with some other information in the form. When I console.log to see the data on the frontend side it work fine but when I print the data on the backend side it return none. By the way, I'm a totally beginner on React and flask so the code might be a little messy.

server.py

@app.route('/api/other',methods=["POST"])
def post_other():
    json_data = request.get_data().decode('utf-8')
    data = json.loads(json_data)
    new_order = line_order(product_type="other",weight=data["weight"],note=data["note"],picture_uuid=data["uuid"],order_status="ordered",create_uid=data["userId"])
    db.session.add(new_order)
    db.session.commit()
    return {'state':'00'}

@app.route("/api/other_img",methods=["POST"])
def post_Other_img():
    data = request.files.get('pic')
    print(data)
    file_name = data.filename
    data.save(os.path.join("/public/static/img/",file_name+".png"))
    return {"state":"00"}

React.js (fetching) Edited

var formData = new FormData();
const changeHandler = (event) => {  
      setSelectedFile(event.target.files[0])
      formData.append("pic",event.target.files[0],uuid+".png")
      for (var pair of formData.entries()) {
        console.log(pair[0]+ ', ' + pair[1]); //This return pic,[object File]
    }
    };
    function handleSave(event){
          event.preventDefault();
            const info = {weight,note,uuid,userId}
            const response = fetch('https://something/api/other',{
              method:'POST',
              mode:"cors"
              ,headers:{
                'Content-Type':'application/json'
              },
              body:JSON.stringify(info)
            }).then(fetch(
              'https://something/api/other_img',
              {
                method: 'POST',
                body: formData,
                mode:"no-cors",
              }
            )
              .then((response) => response.json())
              .then((result) => {
                console.log('Success:', result);
              })
              .catch((error) => {
                console.error('Error:', error);
              }) ).then(history.push('/preview'))
        }

React.js (return)

 return(
        <div className="container">
            <h1>Picture Page</h1>
            <form method="post" onSubmit={handleSave} encType="multipart/form-data">
                <p>weight:</p>
                <div onChange={handleWeight}>
                    <label>
                        <input type="radio" name="weight" value="ones"></input>
                        <span>1 s</span>
                    </label>
                    <label>
                        <input type="radio" name="weight" value="oneb"></input>
                        <span>1 b</span>
                    </label> 
                </div>
                
                <label>image:</label>
                <div className = "file-field input-field">
                    <div className = "btn">
                        <span>Browse</span>
                        <input name="pic" id="pic" type="file" onChange={changeHandler} />
                    </div>
                    
                    <div className = "file-path-wrapper">
                        <input className = "file-path validate" type = "text" placeholder = "Upload a file" />
                    </div>
                </div>    
                <div className="input-field col s6">
                    <input id="note"type="text" name="note" onChange={handleNote} className="validate" onFocus={handlefocusnote} onBlur={handleblurnote}></input>
                    <label className={focusnote} htmlFor="note">Note:</label>
                </div>
                <br></br>
                <input type="submit" value="Save" className="waves-effect waves-light btn"></input>
            </form>
        </div>
        
    )

and this is the error I get from the flask

Traceback (most recent call last):
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 2088, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.handle_exception(e)
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/dolineorder/sgjorder/server.py", line 114, in post_Other_img
    file_name = data.filename
AttributeError: 'NoneType' object has no attribute 'filename'

Note : this code use materialize css for styling.

1 Answer 1

1

Problem

In your React section, after you make the first GET API request, the second POST API request uses a variable called formData as the form value, which is not defined.

.then(fetch(
     'https://something/api/other_img',
     {
        method: 'POST',
        body: formData, // undefined
        mode:"no-cors",
     }
)

And that's why, when you make the request to post_Other_img, data is `None

@app.route("/api/other_img",methods=["POST"])
def post_Other_img():
    data = request.files.get('pic') # This is None

Solution

Make sure that formData is defined in React. Also put your image file in the form data and it should be named pic in the form data because you are accessing request.file.get('pic') in Flask.

I can't give you a specific solution because you didn't specify where your form data is coming from, and how it is formatted. But at least you know what is wrong. If you need more help, please comment on this answer and specify everything starting from where you want to get the formDatafrom and where the image is.

Sign up to request clarification or add additional context in comments.

3 Comments

Oh, I forget to put that part in the question. I will edit the question again
@SorawitC You should probably add a Content-type to the header for your POST request. Content-Type: multipart/form-data
Hello @DevGuyAhnaf, I do not know react, I have very limited knowledge. However, I know flask. I created some code for uploading and the backend sucessfully works. I got a piece of code from the Internet for react part. I was able to modify that and make it work. It uploads images but cannot upload multiple images. Can only upload one. Can you help figure out my mistakes?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.