-1

I have been working on a program in flask that allows you to search a database. I have not coded the actual finding stuff in the data base or anything but I don't need that right now, and the database does not effect anything right now. I have not been able to get past how to get what the user types in the form to the python program. It runs with no errors but when I check what I received I get None. Is there something I'm doing wrong? This is my code, it is very messy and just one file.

main.py

from flask import Flask, render_template
from flask import request
import pdfkit, time




def go(letters):
  data = open('data.txt','r')
  return letters
  
   
app = Flask(__name__)
       
@app.route("/path/", methods=['GET','POST'])
def search():
  time.sleep(1)
  data=request.get_data()
  print(data)
  return go(data)

@app.route('/')
def index():
  
  return render_template('index.html')

if __name__ == "__main__":
    from waitress import serve
    serve(app, host="0.0.0.0", port=8080)
    app.run(debug=True)

templates/index.html

<!Doctype html!>

<html land=en>
<h1>Welcome!</h1><br>
<p>Type to search the database.</p>
<br><form name='this' onsubmit='letsgo()' class='text' action='/path/' method='post'><input id='hey' type='text'> <input type='submit' value='search'></form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var test = document.getElementById('hey').value;
  const xhr = new XMLHttpRequest();
function letsgo() { 
  
  const data = document.getElementById("hey").value
  alert(data)
$.ajax({
  type : 'POST',
  url : "{{'https://file-encrypter.ashwinchera.repl.co/path/'}}",
  dataType: 'data',
  datas : {'data':data}
});
            

};      
</script>

also I am working with a friend, so I don't know what some of this stuff is here for. Can someone tell me how I can send this data? I have been trying things from other questions, but they don't work. Thank you in advance!

DRCoder
  • 21
  • 5
  • What's the problem with the current code exactly? Are you getting errors, or what does "not working" entail exactly? – ggorlen Jan 07 '22 at 15:16
  • @ggorlen, I am not getting errors, but when ever I check what letters is,(what I received) I get None. – DRCoder Jan 07 '22 at 15:34
  • You're treating a string like it's a template without using `render_template`. That won't end well -- if you open the JS console, you should see errors. `alert(url_for(view./path/))` in the JS doesn't use Jinja template injection curlies, so you're definitely going to get an error trying to run Python code as JS in the browser. – ggorlen Jan 07 '22 at 15:38
  • Also, are you sure jQuery has been imported to the front end? If so, please show where. `const xhr = new XMLHttpRequest();` is created and never used, so the code smells like it was cobbled together without much understanding or process, if you'll pardon my frankness. – ggorlen Jan 07 '22 at 15:45
  • Im very new to flask, (I started two days ago) and every time I try render_template it has the error `jinja2.exceptions.TemplateNotFound: index.html` with alot of errors before it. and the other way works, so I've been using it. – DRCoder Jan 07 '22 at 15:46
  • I think you need to break the problem down into simpler steps and validate that each step works before jumping ahead -- you have too many errors all at once here. Do you have a `templates/index.html` file? A basic Flask tutorial will cover everything you need here, and I'm sure there are many duplicate questions that show a basic form submission workflow. – ggorlen Jan 07 '22 at 15:47
  • @ggorlen I have looked at it and done my render template and added jquery, but when I print the data it comes out as `b' '` – DRCoder Jan 07 '22 at 16:00
  • Thanks for the edit -- this code looks more actionable. – ggorlen Jan 07 '22 at 16:03
  • I notice you have both an `onsubmit` and an `action` on your form. Are you trying to do an AJAX POST (without refresh) or do you want to redirect the user and render a new page in the response? I assume the former. Are you trying to send JSON or form data? – ggorlen Jan 07 '22 at 16:12
  • I am trying to send form data, an have the user go to a page that will show something that changes based on the data sent. I first thought that the post was being sent after the page was went to and that's why I put i the `time.sleep()`. I am trying to send what is in the text box. – DRCoder Jan 07 '22 at 16:21
  • Hmm -- I answered assuming AJAX, but I can update to show a redirect if you want. – ggorlen Jan 07 '22 at 16:55

1 Answers1

0

There are multiple issues here. As mentioned in the comments, I recommend working slowly and breaking the problem down into small pieces. Check that each piece works before rushing ahead and accumulating many errors that are hard to unravel.

Most of the problems are on the front-end, so you'll want to use the browser console to inspect errors. You can also use an HTML validator tool to make sure your HTML makes sense and catches typos like land=en.

Since it sounds like you want to POST without a page refresh and you're using jQuery, many properties on your form are unnecessary:

onsubmit='letsgo()' action='/path/' method='post'

can all be removed. While you're at it, remove any unused noise like:

var test = document.getElementById('hey').value;
  const xhr = new XMLHttpRequest();

and unnecessary ids and classes. These are just adding to the confusion. When things don't make sense and aren't working, try stripping out code rather than adding it.

"{{'https://file-encrypter.ashwinchera.repl.co/path/'}}" should just be /path so that it'll work on any domain such as a localhost. If you're working cross-origin, that's another story, but I don't think you are.

In the $.ajax call, datas is a typo. That should be data.

const data = document.getElementById("hey").value isn't necessary. If you're bothering to import jQuery, you might as well use it all the way: $("#hey").val(). #hey and letsgo are unclear names that don't make it any easier to debug the app.

Use event.preventDefault() to prevent the form submission.

On the backend, once again, remove any cruft and noise like the file read and import pdfkit, time. It seems strange to add GET to the list of accepted verbs for the /path route (which is too generically-named, as is go).

Since you're using form data, request.get_data() can be request.form.get("data") where "data" is the key you want to retrieve from the parsed form.

Here's a minimal AJAX example to get you moving:

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
  <h1>Welcome!</h1>
  <p>Type to search the database.</p>
  <form>
    <input id="search-term">
    <input type="submit" value="search">
  </form>
  <div id="result"></div>

<script>
$("form").submit(function (event) {
  event.preventDefault();
  var data = $("#search-term").val();
  $.ajax({
    type: "POST",
    url: "search",
    data: {data},
    success: data => $("#result").text(data),
    error: res => console.error(res),
  });
});      
</script>
</body>
</html>

app.py:

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/search", methods=["POST"])
def search():
    data = request.form.get("data")
    print(data)
    return data

@app.route("/")
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)

If you want to submit and render a new page, you don't need jQuery:

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<body>
  <h1>Welcome!</h1>
  <p>Type to search the database.</p>
  <form action="/" method="post">
    <input name="search-term">
    <input type="submit" value="search">
  </form>
  <div>{{search_term}}</div>
</body>
</html>

app.py:

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def index():
    search_term = request.form.get("search-term", "")
    return render_template("index.html", search_term=search_term) 

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)

Or point to another page:

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<body>
  <h1>Welcome!</h1>
  <p>Type to search the database.</p>
  <form action="/search" method="post">
    <input name="search-term">
    <input type="submit" value="search">
  </form>
</body>
</html>

templates/search.html:

<!DOCTYPE html>
<html lang="en">
<body>
  <p>You searched: '{{search_term}}'</p>
</body>
</html>

app.py:

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/search", methods=["POST"])
def search():
    search_term = request.form.get("search-term", "")
    return render_template("search.html", search_term=search_term) 

@app.route("/")
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)
ggorlen
  • 44,755
  • 7
  • 76
  • 106