0

I'm working on an example project for a course and am getting the error:

TypeError("'NoneType' object is not subscriptable"

and in my browser I'm sreing:

Bad Request The browser (or proxy) sent a request that this server could not understand.

I don't know what I'm doing wrong here. I'm using flask, sqlalchemy, postgresql and python 3 and I can't figure out what's going wrong. This is my code:

app.py:

#!/usr/bin/python3

from flask_sqlalchemy import SQLAlchemy
from flask import Flask, render_template, request, redirect, url_for, jsonify, abort
import sys

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:[email protected]:5432/todoapp'
db = SQLAlchemy(app)
#db = SQLAlchemy(app, session_options={"expire_on_commit": False})

class Todo(db.Model):
    __tablename__ = 'todos'
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(), nullable=False)

#   def __repr__(self):
#       return f'<Todo {self.id} {self.description}>'   

db.create_all()

#todo1 = Todo(description='Todo Thing 1')
#db.session.add(todo1)
#db.session.commit()



@app.route('/')
def index():
    return render_template('index.html', data=Todo.query.all())

@app.route('/todos/create', methods=['POST'])
def create_todo():
    error = False
    body = {}
#   description = request.form.get('description', '')
#   return render_template('index.html')
    try:
        description = request.get_json()['description']
        todo = Todo(description=description)
        #body['description'] = todo.description
        db.session.add(todo)
        db.session.commit()
    except:
        error=True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()
    if error:
        abort (400)
    else:
        return jsonify(body)
#       return jsonify({
#           'description': todo.description
#       })

#   return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

index.html

<html>
    <head>
        <title>Todo App</title>
        <style>
            .hidden {
                display: none;
            }
        </style>
    </head>

    <body>
        <form method="POST" action="/todos/create">
            <input type="text" id="description" name="description" />
            <input type="submit" value="Create" />
        </form>
        <div id="error" class="hidden">Something went wrong</div>
        <ul id="todos">
            {% for d in data %}
                <li>{{d.description}}</li>
            {% endfor %}
        </ul>

        <script>
            document.getElementById('form').onsubmit = function(e) {
                e.preventDefault();
                userInput = document.getElementById('description').value
                fetch('/todos/create', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({'description': userInput})
                })
                .then(function(response) {
                    return response.json();
                })
                .then(function(jsonResponse){
                    console.log(jsonResponse);
                    let liItem = document.createElement('LI');
                    liItem.innerHTML = jsonResponse('description');
                    document.getElementById('todos').appendChild(liItem);
                    document.getElementById('error').className = 'hidden';
                })
                .catch(function() {
                    document.getElementById('error').className = '';
                })
            }
        </script>
    </body>

</html>
4
  • Failed to load resource: the server responded with a status of 400 (BAD REQUEST) Commented May 3, 2020 at 16:43
  • that's what shows in the dev tools Commented May 3, 2020 at 16:52
  • Are you sending any payload with your post? And is that payload valid json? Commented May 3, 2020 at 17:06
  • I think I'm doing it with this. body: JSON.stringify({'description': userInput}). how do i know uif i'm sending the payload? Commented May 3, 2020 at 17:15

1 Answer 1

2

You didn't give your form an id.

<form method="POST" action="/todos/create" id="form">

I found this problem using the dev tools that @snakecharmerb mentioned.

Then you were trying to access the 'description' as if jsonResponse was a function. Since it is JSON you need the square brackets around description: ['description'].

                .then(response => {
                    return response.json()
                })
                .then(jsonResponse => {
                    let liItem = document.createElement('li');
                    liItem.innerHTML = jsonResponse['description'];
Sign up to request clarification or add additional context in comments.

Comments

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.