Asking Two Prompts and Not Making Tasks

Question:
I am making a To-Do Extension using Flask, and it is supposed to create and save tasks. It asks for a task name and makes an element, but it asks twice instead of once. It then saves it to the JSON and it is supposed to access it and create tasks so the user doesn’t lose all of their work.

Repl link:
https://replit.com/@SalladShooter/To-Do-Extension

from flask import Flask, render_template, request, jsonify
import json

app = Flask(__name__)

# Path to the JSON file to store tasks
JSON_FILE_PATH = 'database/data.json'

def load_tasks():
    try:
        with open(JSON_FILE_PATH, 'r') as file:
            tasks = json.load(file)
    except FileNotFoundError:
        tasks = {'tasks': []}  # Initialize tasks as a dictionary with a 'tasks' key
    return tasks.get('tasks', [])  # Return the 'tasks' key or an empty list if it doesn't exist

def save_tasks(tasks):
    with open(JSON_FILE_PATH, 'w') as file:
        json.dump({'tasks': tasks}, file)  # Save tasks as a dictionary with a 'tasks' key

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        task_data = request.form.get('task_data')
        if task_data:
            tasks = load_tasks()
            tasks.append(task_data)
            save_tasks(tasks)

    tasks = load_tasks()
    return render_template('index.html', tasks=tasks)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000) 
{% extends 'base.html' %}

{% block title %}To-Do Extension{% endblock %}
    
{% block content %}
    <h1>To-Do Extension</h1>
    <div class="create-task">
        <p>Create Task</p>
        <span class="material-symbols-outlined">
        add_circle
        </span>
    </div>
    <div class="task-list"></div>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            console.log('Document is ready!');

            var createTaskButton = document.querySelector('.create-task');
            console.log('Create task button:', createTaskButton);

            var taskList = document.querySelector('.task-list');
            console.log('Task list:', taskList);

            // ... (other log statements)

            createTaskButton.addEventListener('click', function () {
                console.log('Create task button clicked!');

                // Prompt the user to enter a task name
                var taskText = prompt('Enter task name:');
                console.log('Task text entered:', taskText);

                // ... (other log statements)

                if (taskText) {
                    addTask(taskText);
                }
            });

            // Function to add a task to the list
            function addTask(taskText) {
                // Create a new task element
                var taskElement = document.createElement('div');
                taskElement.className = 'task';
                taskElement.textContent = taskText;

                // Append the task to the list
                taskList.appendChild(taskElement);
            }
        });
    </script>
{% endblock %} 
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap');

@media (prefers-color-scheme: dark) {
    :root {
        --back: #212425;
        --back-accent: #313435;
        --fore: white;
        --primary: #1c96c0;
        --primary-accent: #4cc6f0;
        --danger: #f04a64f;
        --shadow: rgba(0,0,0,0.3);
        --font: 'Poppins', Arial; 
        --font-size: 1.5em;
    }
}
@media (prefers-color-scheme: light) {
    :root {
        --back: white;
        --back-accent: #eee;
        --fore: black;
        --primary: #1c96c0;
        --primary-accent: #4cc6f0;
        --danger: #f04a64f;
        --shadow: rgba(0,0,0,0.3);
        --font: 'Poppins', Arial; 
        --font-szie: 1.5em;
    }
}

html {
    width: 100%;
    height: 100%;
    background: var(--back);
    color: var(--fore);
    font-family: var(--font);
}

h1 {
    text-align: center;
    margin: auto;
    border-bottom: 2px solid var(--primary);
    width: fit-content;
    padding: 2px;
    font-size: calc(1em + 1rem);
}

.create-task {
    text-align: center;
    justify-content: center;
    font-size: var(--font-size);
    position: relative;
    margin: auto;
    margin-top: 3em;
    width: 92.5%;
    max-width: 500px;
    aspect-ratio: 4 / 1;
    background: var(--back-accent);
    border-radius: 14px;
    padding: 5px;
    box-shadow: 0 5px 5px 0 var(--shadow);
    transition: 0.3s ease-in-out all;
}

.create-task:hover {
    box-shadow: 0 10px 10px 0 var(--shadow);
    background: linear-gradient(to left top, var(--primary), var(--primary-accent));
}

.create-task:hover span {
    color: var(--fore);
}

.create-task p {
    text-align: center;
    justify-content: center;
    font-size: calc(0.5em + 1rem);
}

.create-task span {
    position: absolute;
    top: 0;
    right: 0;
    font-size: calc(var(--font-size) - 0.5em);
    margin: 4px;
    color: var(--primary);
    border-radius: 50%;
    cusor: pointer;
    transition: 0.3s ease-in-out all;
    transform: scale(1);
    box-shadow: 0 0 0 0 var(--shadow);
}

.task {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-size: var(--font-size);
    position: relative;
    margin: auto;
    margin-top: 1em;
    width: 92.5%;
    max-width: 500px;
    aspect-ratio: 4 / 1;
    background: var(--back-accent);
    border-radius: 14px;
    padding: 5px;
    box-shadow: 0 5px 5px 0 var(--shadow);
    transition: 0.3s ease-in-out all;
} 
document.addEventListener('DOMContentLoaded', function () {
    var createTaskButton = document.querySelector('.create-task');
    var taskList = document.querySelector('.task-list');

    // Function to add a task to the list
    function addTask(taskText) {
        var taskElement = document.createElement('div');
        taskElement.className = 'task';
        taskElement.textContent = taskText;

        taskList.appendChild(taskElement);
    }

    // Click event listener for the "create task" button
    createTaskButton.addEventListener('click', function () {
        var taskText = prompt('Enter task name:');
        if (taskText) {
            // Make an AJAX request to the Flask server to save the new task
            fetch('/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'task_data=' + encodeURIComponent(taskText),
            })
            .then(response => response.json())
            .then(data => {
                // Handle the response if needed
                console.log('Server response:', data);

                // Add the task to the front-end task list
                addTask(taskText);
            });
        }
    });

    // Load existing tasks from the server
    fetch('/')
        .then(response => response.json())
        .then(data => {
            data.tasks.forEach(task => {
                addTask(task);
            });
        });
}); 

You are doing the same thing in your script in index.html and in your script.js file.

I’d suggest you remove the redundant code from index.html to prevent the double prompt.

Also, modify the POST endpoint to return a JSON response.

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        task_data = request.form.get('task_data')
        if task_data:
            tasks = load_tasks()
            tasks.append(task_data)
            save_tasks(tasks)
            return jsonify({'status': 'success', 'message': 'Task added'})
    
    tasks = load_tasks()
    return render_template('index.html', tasks=tasks)
3 Likes

@WindLother I removed the JS from index.html and replaced the POST endpoint in the main.py file, but it is still not working. I am also not getting any errors.

There are no errors in the console web browser and in the Flask log?

Correct, there aren’t any errors.

Hmm, it may be a mismatch with the fetch.

Try to separate the route for the task data

@app.route('/tasks', methods=['GET'])
def get_tasks():
    tasks = load_tasks()
    return jsonify(tasks)

And update the javascript with the new route

fetch('/tasks')
    .then(response => response.json())
    .then(tasks => {
        tasks.forEach(task => {
            addTask(task);
        });
    });

And see if the JSON is being initialized correctly with the tasks like

{
  "tasks": ["Task 1", "Task 2", ...]
}

Tell me if works

1 Like

It worked perfectly! Thanks for your help!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.