Home > OS >  Flask POST 404 Error and Dynamic Data Update
Flask POST 404 Error and Dynamic Data Update

Time:07-31

I'm trying to make a Flask web that has a pomodoro timer where the user can set the timer themselves.

Here's my code: app.py

import time
from flask import Flask, render_template, url_for, flash, redirect, request, jsonify
app = Flask(__name__)


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


# Get is for loading that page; Post is for submitting the "form" / set timer
@app.route("/pomodoro.html", methods=["GET", "POST"])
def pomodoro():

    if request.method == "POST":

        # Cast user inputs as int and store in variables
        hours = int(request.form.get("hours"))
        minutes = int(request.form.get("minutes"))
        seconds = int(request.form.get("seconds"))

        # Check if user input is valid aka no negative numbers
        if hours < 0 or minutes < 0 or seconds < 0:
            return apology("There is no negative time...", 400)
        
        # Check if the input is blank. If so, replace with 0
        if not hours:
            hours = 0
        elif not minutes:
            minutes = 0
        elif not seconds:
            seconds = 0

        # Calculate total number of seconds from the user inputs
        totalTime = hours * 3600   minutes * 60   seconds
        print(totalTime)

        # Countdown timer
        while(totalTime > -1):
            # Call the function to start countdown
            hours, minutes, seconds = runTimer(totalTime)
            totalTime -= 1
            return jsonify({'hours' : hours, 'minutes' : minutes, 'seconds' : seconds})
        
        # Let the user know if the time has expired 
        if(totalTime == 0):
            flash("Time's up")       

    # User reached route via GET (as by clicking a link or via redirect)
    else:
        return render_template("pomodoro.html")


# Figure out how many h, m, s there are and store them in total variables
def runTimer(totaltime):

    # Divmod returns 2 values. Ex. 10/5 then totalMin will be 2 and totalSec, or the remainder, will be 0
    # Parameter is totaltime / 60
    totalMinutes, totalSeconds = divmod(totaltime, 60)

    totalHours = 0
    if(totalMinutes > 60):
        totalHours, totalMinutes = divmod(totalMinutes, 60)

    return totalSeconds, totalMinutes, totalHours


if __name__ == "__main__":
    app.run(debug=True)

pomodoro.html

{% extends "layout.html" %}

{% block title %}
    Pomodoro
{% endblock %}

{% block script %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
<script type="text/javascript">
    // This function will be executed after the HTML is loaded
    $(document).ready(function() {

        // When the submit button is clicked, the function with AJAX starts
        $('#start_button').on('submit',  function(e) {
            // Prevent event default before starting an ajax call
            e.preventDefault();
            console.log("Hello");

            $.ajax({
                data : {
                // Key : value pair. 
                sec : $('#seconds').val(),
                min : $('#minutes').val(),
                hr : $('#hours').val(),
                },
                type : 'POST',
                // Where to get the data
                url : '/pomodoro',
                // After data is obtained, update values
                success: function(data) {
                $('#hours').val(data.hours);
                $('#minutes').val(data.minutes);
                $('#seconds').val(data.seconds);
                } 
            });
        })
    });

</script>
{% endblock %}

{% block main %}
    <form action="/pomodoro" method="post">
        <div id="countdown_container">
            <ul>
                <li><input type="number" id="hours" name="hours" placeholder="Hours" value="{{ request.form.hours }}"></li>
                <li><input type="number" id="minutes" name="minutes" placeholder="Minutes"></li>
                <li><input type="number" id="seconds" name="seconds" placeholder="Seconds"></li>
            </ul>
        </div>

        <div id="buttons_container">
            <button id="start_button" type="submit" >Start</button>
            <button id="cancel_button" type="button" >Cancel</button>
        </div>
    </form>

{% endblock %}

I have 2 questions about my code.

  1. I'm getting a POST 404 error. My GET works fine. I tried printing in app.py and pomodoro.html but neither showed up. I tried using the debugger but perhaps I was doing it wrong, the debugger wouldn't let me go into my def pomodoro function to check the specifics. I double checked my spelling and syntax so hopefully there's no careless mistake.

  2. Right now, my pomodoro is being calculated in app.py then the information is sent over to pomodoro.html. Am I on the right track? I'm not sure if this will allow dynamic data update on the webpage.

Thank you!

CodePudding user response:

Your app route is "/pomodoro.html" and your form is posting to "/pomodoro", I don't think the form can actually properly post anywhere. Try matching your route in app.py and where the form posts to in pomodoro.html

  • Related