I am getting a HTML 405 error usingPOST and flask, unsure why

I am a fairly recent/new programmer, and have been learning using flask to communicate between python and javascript for a website I’m working on.

Currently am on the signup/login page and I have a signup.html page with a form for 3 user inputs: username, password and email address. I have tried to use flask so that for a valid form submission the 3 user inputs are posted from the html based form using POST method to an app.py file, where they are then added to a sqlite3 database provided the email/username is not already in the database. Currently I am just checking to make sure whenever the submit button is clicked and all 3 fields are filled, the entry is added to the database, for which I am using writing to a text file

However whenever I try to entr sample user details which are valid and press submit, I check the text file and it is empty, meaning the database has not been appended to. When i press inspect and chek the console on the html signup page, it shows this error:
POST http://127.0.0.1:5500/submit 405 (Method Not Allowed), signupPage line 20.

Would really appreciate if someone could take time out and help with this a it is quite importan, and please give a slightly detailed answer as I am a bit new to programming so I probably wont understand vague responses.

My code is attached below for app.py and signupPage (html and js) –

signupPage.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Signup - Educational Car Racing Game</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>Signup</h1>
        <nav>
            <ul>
                <li><a href="loginPage.html">Already have an account? Login here</a></li>
                <li><a href="homepage.html">Return to Homepage</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <!-- Signup form -->
        <form id="signupForm">
            <input type="text" placeholder="Username" id="username">
            <input type="password" placeholder="Password" id="password">
            <input type="email" placeholder="Email" id="email">
            <button type="submit">Sign Up</button>
        </form>
    </main>
    <footer>
        <!-- Footer content -->
    </footer>
    <script src="signupPage.js"></script>
</body>
</html>

signupPage.js:

document.getElementById('signupForm').addEventListener('submit', function(e) {

    e.preventDefault();

    // Get form data
    const username = document.getElementById('username').value;
    const password = document.getElementById('password').value;
    const email = document.getElementById('email').value;

    // Validate form data (you might want to add more validation)
    if (username && password && email) {
        // Prepare data to send
        const data = {
            username: username,
            password: password,
            email: email
        };

        // Send data to the server using AJAX
        fetch ('/submit', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })
        .then(response => response.json())
        .then(result => {
            // Handle server response (if needed)
            window.alert(result);
        })
        .catch(error => {
            // Handle errors
            window.alert('Error:', error);
        });
    } else {
        window.alert('Please fill in all fields');
    }
});

app.py:

from flask import Flask, request, jsonify
import sqlite3
import hashlib

app = Flask(__name__)

# Create a connection to a SQLite database (or open if it exists)
conn = sqlite3.connect('userdata.db')

# Create a cursor object to execute SQL queries
cursor = conn.cursor()

# Create a table if it doesn't exist already
cursor.execute("CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY AUTOINCREMENT,  username          TEXT, password TEXT, email TEXT UNIQUE)")

conn.commit()

@app.route('/submit', methods=['GET','POST'])
def submit():
    if request.method == 'POST':
        data = request.get_json()

        # Access data received from JavaScript
        username = data.get('username')
        password = data.get('password')
        email = data.get('email')

    # Hash the password before storing
    hashed_password = hashlib.sha256(password.encode()).hexdigest()

        # Store the username, password, hashed password and email address in text file.
        with open('TEXT.txt', 'a') as file:
                file.write(f"Username: {username}, Password: {password}, Hashed Password:       {hashed_password}, Email: {email}n")

        # Check if the email already exists in the database
        cursor.execute("SELECT * FROM users WHERE email=?", (email,))
        existing_user = cursor.fetchone()

        if existing_user:
            response = {'message': 'Email already exists in the database'}
        else:
            # Insert new user into the database with hashed password
            cursor.execute("INSERT INTO users (username, password, email) VALUES (?, ?, ?)",   (username, hashed_password, email))
            conn.commit()
            response = {'message': 'Data received and added to the database'}

        return jsonify(response)

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

# Close the database connection when the app exits
conn.close()

How to Integrate SCORM Package in React Application with react-scorm-provider?

I’m attempting to integrate a SCORM package into a React application using the react-scorm-provider library. My goal is to display a SCORM package in an iframe and then access SCORM data such as student name, status, and tracking information. However, I’m struggling to establish a connection with the SCORM API to retrieve this data.

Here is the structure of my code:
Parent Component (App.js):

import React from "react";
import "./styles.css";
import ScormProvider from "react-scorm-provider";
 import Scorm from "components/Scorm";

export default function App() {
  return (
    <ScormProvider version="1.2" debug={true}>
      <div className="App">
        <h1>Quiz</h1>
        <hr />
        <Scorm />
      </div>
    </ScormProvider>
  );
}

Child Component (Scorm.jsx):

import React from "react";
import { withScorm } from "react-scorm-provider";

const Scorm = (props) => {
    return (
      <div>
        <iframe
          src="https://louuu03.github.io/Scorm_Example/story.html"
          height="600px"
          width="900px"
          title="Scorm Package URL"
        />
        <br />
        <button onClick={() => { console.log(props); }}>
          Click Me
        </button>
      </div>
    );
}

export default withScorm()(Scorm);

Function to render notification React component

I created a custom notification (toast). It’s part of custom UI library and the component is as simple as

<Notification message="Success!" close={()=>console.log('Close notification')} />

I know I can place Notification component in some top level app component, usually called index.js or App.js and then message could be stored in some global store like redux, however I’m looking for a way to create some utility function to simply call shawNotification from whatever place in the app. NOTE – I wanna support not only React components (also places like sagas, redux actions etc.) so it cannot be as a hook. The ideal API would be:

showNotification('Success!', ()=>console.log('Close notification'));

And it would render a Notification component for 5 seconds. I cannot find any example of such functionality, would appreciate any help, could be even article links.

Split the sentence into words and reverse in JavaScript

I am trying to break the whole sentence into reverse words, in this case, why do we use let i = splittedText.length-1 instead of let i = splittedText.length?
Why do we need to subtract 1?

const wordSplit = (text) => {
    let splittedText = text.split(" ");
    let reversedWords = [];
    for(let i = splittedText.length-1; i>=0; i--){
        let ele = splittedText[i];
        reversedWords.push(ele);
    }
    const result = reversedWords.join(" ");
    return result;
};

const myWord = "I will solve the problem";
console.log( wordSplit(myWord));

Facing difficulty in understanding async await

I’m a beginner. Got confused about async programming after seeing the output of this code

async function f1() {
   console.log('this is f1');
  let res = await f3();
  console.log('result of f1 from f3 = ', res['status']);
  console.log('end of f1');
}

async function f3() {
  console.log('this is f3') 
  console.log('returning res from f3');
  return {"status": 600} ;
}

f1();
console.log('inside global context');

Now my doubt is even though there is no async work going on in f3() as everthing is console logs and a simple return, why don’t the output returned by f3 gets printed immediately in f1(), rather first the inside global context gets printed and then the console logs of f1() gets printed. What exactly did f3 return (I assume a resolved promise) and why didn’t f1 immediately used it ?
If I’m not wrong f1 is still inside call stack when f3 returns a json

Render inside the TextField [closed]

I wanna create a Chat Message Input. I want it similar to Teams chat input or Slack chat input, where attached files are shown below the messages with close icon.
Could you please tell how to achieve it?

I tried different approach with input tag and MUI text field and using endAdorment, its not how I wanted.
And using MUI Autocomplete still same.

I dont wanna use any 3rd party integrations. Wanna achieve it with MUI or simple html.

Click here to see how I actually wanted it

Any way to disable drag in mobile view for react-beautiful-dnd?

I used react-beautiful-dnd package in my project. Where I want to disable the drag option in mobile view(e.g window.innerwidth < 768 or something), but it will work properly in desktop view.
I tried using the prop isDragDisabled, but it is not working.
Here is what I have done so far,

function ProductItem({
  objectId,
  name,
  availability,
  images = [],
  idx,
  category,
}) {
  const [isMobileView, setIsMobileView] = useState(window.innerWidth < 768);

  useEffect(() => {
    const handleResize = () => {
      setIsMobileView(window.innerWidth < 768);
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  return (
    <Draggable
      draggableId={`${category}-${idx}`}
      index={idx}
      isDragDisabled={isMobileView}
    >
      {(provided) => {
        return (
          <div
            key={idx}
            className="item"
            ref={provided.innerRef}
            {...provided.draggableProps}
            {...provided.dragHandleProps}
          >
            <img src={images[0]} alt="restaurant" />
            <div>
              <h3 className="title">{name}</h3>
            </div>
            <ProductAvailability id={objectId} availability={availability} />
            {provided.placeholder}
          </div>
        );
      }}
    </Draggable>
  );
}

Is there a way to prevent my for loop doubling duplicate letters when comparing two strings for identical letters?

I’ve got an array of strings and a string. Using a for loop, iterating through both the array and the string, I’m hoping to return the letters that are the same in both.

My solution works until there is a duplicate letter in the array. When there is a duplicate, the
relevant letter gets doubled, for example ‘aaa’ would return ‘aaaaaa’.

Below is the code that I have tried most recently.

const fruits = ["Banana", "Orange", "Apple", "Mango", "Apple"];

let myString = "apple";

const fruit = fruits[2].toLowerCase();

for (let i = 0; i < fruit.length; i++) {
  for (let j = 0; j < myString.length; j++) {
    if (myString[j].indexOf(fruit[i]) !== -1) {
      console.log(myString[j]);
      return myString(j)
    }
  }
}

Create new window in Arc browser extension

Ultimate goal is to open new tabs in different windows in Arc browser.

I’m currently trying to write an extension (based on “New Tab, New Window” https://chromewebstore.google.com/detail/new-tab-new-window/dndlcbaomdoggooaficldplkcmkfpgff) to work similar with “Open Link in New Window” right-click command. I’m on macOS.

Question: In chrome extension, how to open new window? The code below works in Chrome, but in Arc it opens a new Little Arc, not a new window.

import {getOption, setOption} from "./lib/option.js";

chrome.tabs.onCreated.addListener(function(tab){
    if (tab.index == 0){
        console.log('First Tab'); 
        return;
    } 
    const createData = {
        tabId: tab.id, 
        focused: true, 
        incognito: tab.incognito, 
        setSelfAsOpener: true, 
        type: "popup"
    }; 
    chrome.windows.create(createData); 
});

Note: In Arc, all windows list the same tabs, all tabs belonging to the current space. So it’s enough if the extension opens a new window and activates the respective new tab in it.

Show only the dates on Google charts’ Timeline chart

I have a timeline chart using the following code:

      google.charts.load("current", {packages:["timeline"],'language': 'pt'});
        google.charts.setOnLoadCallback(drawChart);
        function drawChart() {


            var jsonData = $.ajax({
                url : 'Consulta/getDados',
                dataType : 'json',
                async: false

            }).responseText;

            //console.log(jsonData);

            var container = document.getElementById('chart');
            var chart = new google.visualization.Timeline(container);
            var dataTable = new google.visualization.DataTable(jsonData);
            google.visualization.events.addListener(chart, 'ready', afterDraw);

            var options ={
              timeline: { showRowLabels: false},
              alternatingRowStyle: true,
               hAxis: {
                format: 'dd.MM.yyyy',
                }
            };

            chart.draw(dataTable,
                {
                    width: '100%',
                    height: 1000
                });
        }

Im gathering data from a database and using it on the graph.
The ‘afterDraw’ function that it uses is just to set the x Axis on top of the graph instead of at the bottom. Will put it here anyway to make sure the problem isnt on it.

   function afterDraw() {
        var g = document.getElementsByTagName("svg")[0].getElementsByTagName("g")[1];
        document.getElementsByTagName("svg")[0].parentNode.style.top = '45px';
        document.getElementsByTagName("svg")[0].style.overflow = 'visible';
        var height = Number(g.getElementsByTagName("text")[0].getAttribute('y')) + 20;
        g.setAttribute('transform','translate(0,-'+height+')');
        g = null;
    }

My problem is that if i select a certain amount of days, specifically less than 6 days in total, the graph stop showing the dates on the x axis and start to show hours, like so:

Correct way:
What should happen

If i filter for less than 6 days:
Wrong way

i’ve tried using ticks and the hAxis property on the options, but didnt have any success.

How do i make it show only days, even if the specified date spam is less than a week?

what navigation system can i use for web app? [closed]

i need to create a mobile app, an ecommerce. Wich kind of navigation is better, to mantain the same components changing always just the content or upload always new pages? Thanks.

ps. my stack will be react + next.js + node.js + mysql.

I want that the app will be user friendly and as fast as possible.

Button click reloads page, although using event.preventDefault();

I’m really unexperienced in JavaScript, but as a web dev in PHP I still need it sometimes. I have a really small form for a chat with a model from openAI. I simply write a message in my textarea, click the button and it should call an ajax request which calls my PHP Script in the backend.

Yesterday everything worked fine. It executed the code and gave me the response of the ai in the frontend without reloading the whole page and adding parameters. Now I just started my pc, opened my local WebServer to test it and when I click on the button, it just reloads the page, adds two parameters in the url. Example prompt: “What is PHP?”. Page reloads -> URL: /ai-client/?prompt_text=What+is+PHP%3F&generate_button=

I already used event.preventDefault();, that’s why it worked yesterday. But now I have no idea.

Thank you in advance!

aiclient.html.php:

addTextAreaEventListener('prompt-text', 'input');

//Hinzufügen des Event-Listeners für das Textfeld
function addTextAreaEventListener(id, event) {
  document.addEventListener('DOMContentLoaded', () => {
    const textarea = document.getElementById(id);
    textarea.addEventListener(event, autoResize, false);
  }
}

//Automatische Vergrößerung des Textfeldes bei Eingabe
function autoResize() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight + 'px';
}

(function ($) {
  let chatHistory = [];

  let $generateButton = $('#generate-button');
  $generateButton.on('click', function (event) {
    event.preventDefault();

    //Festlegen der Variablen für die User-Eingabe
    let promptText = $('#prompt-text');
    let userInput = promptText.val();

    //Hinzufügen des User-Inputs zur Chat-History
    chatHistory.push({role: 'user', message: userInput});

    //Erstellen der HTML-Elemente für die Anzeige des User-Inputs
    let userDiv = $('<div>').addClass('user-response').text(`User: ${userInput}`);
    $('#response-container').prepend(userDiv);
    promptText.prop('readOnly', true);

    //Senden der User-Eingabe, sowie der bisherigen Chat-History an den Server
    $.post(
      '<?= $view['cms_file']->resourceUrl('cms/php/aiclient/ajax/generate.php') ?>',
      {prompt_text: promptText.val(), chat_history: chatHistory},
      function (data) {
        let response = data.completed_text;

        //Erstellen der HTML-Elemente für die AI-Response
        let aiDiv = $('<div>').addClass('ai-response').text(`Assistent: ${response}`);
        $('#response-container').prepend(aiDiv);

        //AI-Response zur History hinzufügen
        chatHistory.push({role: 'assistant', message: response});

        //Textfeld für neue Eingabe freigeben
        promptText.val('');
        promptText.prop('readOnly', false);
      }
    );
  });
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
    <div>
        <div id="response-container">
        </div>
        <br/>
        <div class="input-wrapper">
            <textarea name="prompt_text" id="prompt-text" placeholder="Text eingeben..."></textarea>
            <button name="generate_button" id="generate-button"><img
                    src="https://cdn-icons-png.flaticon.com/128/8220/8220580.png" alt="Senden"/></button>
        </div>
    </div>
</form>

React MultiSelect Component Not Updating Available Options After Selection

I’m working on a React component called MultiSelect that allows users to select multiple options from a dropdown. Once an option is selected, it should no longer be available for selection in the dropdown. The selected options are displayed as labels above the dropdown, and users can remove them if needed.

Issue: The dropdown is not updating to exclude the selected options. Even after a user selects an option, it still appears in the dropdown list.

What I’ve Tried:

  1. Maintaining a selectedItems state to track the selected options.
  2. Filtering the available options in the render method of the component based on the selectedItems.
  3. Adding a useEffect hook to update the available options when selectedItems changes (also tried without useEffect).

Current Behavior: Despite these implementations, the dropdown still shows options that have already been selected.

Expected Behavior: Once an option is selected, it should not appear in the dropdown list.

MultiSelect.tsx

"use client";
import React, { useState, useEffect } from "react";
import Dropdown from "@/app/components/Dropdown";
import Label from "@/app/components/Label";

const MultiSelect = ({ label, options }) => {
  const [selectedItems, setSelectedItems] = useState([]);

  const getItemLabel = (item) => item.label;

  const handleMultiSelect = (event) => {
    const selectedIndex = event.target.selectedIndex;
    const itemValue = event.target.value;
    const itemLabel = event.target.options[selectedIndex].dataset.label;
    const selectedItem = { value: itemValue, label: itemLabel };

    if (!selectedItems.some((item) => item.value === itemValue)) {
      const newSelectedItems = [...selectedItems, selectedItem];
      setSelectedItems(newSelectedItems);
    }
  };

  const handleCloseItem = (event) => {
    const itemValue =
      event.currentTarget.parentElement.querySelector("p").dataset.value;
    const updatedItems = selectedItems.filter(
      (item) => item.value !== itemValue
    );
    setSelectedItems(updatedItems);
  };

  const availableOptions = options.filter(
    (option) => !selectedItems.some((item) => item.value === option.value)
  );

  return (
    <div className="">
      <div
        className={
          "selectedItems border-2 border-accent2 rounded-md border-dashed p-2 mb-2 flex gap-4 flex-wrap" +
          (selectedItems.length === 0 ? " hidden" : "")
        }
      >
        {selectedItems.map((item) => (
          <Label
            key={item.value}
            onClick={handleCloseItem}
            itemName={getItemLabel(item)}
            itemValue={item.value}
            isHidden={false}
          />
        ))}
      </div>
      <Dropdown
        id="items"
        label={label}
        defaultValue="Item"
        onChange={handleMultiSelect}
        options={availableOptions}
      />
    </div>
  );
};

export default MultiSelect;

Dropdown.tsx

import React from "react";

const Dropdown = ({ id, options, label, value, onChange, required }) => {
  return (
    <div className="flex flex-col mb-4 relative">
      <label htmlFor={id} className="text-md font-bold mb-2">
        {label + (required ? "*" : "")}
      </label>
      <select
        name={id}
        id={id}
        {...(required && { required: true })}
        value={value}
        onChange={onChange}
        className="block appearance-none border-2 rounded-md border-primaryDark px-4 py-2 pr-8 shadow leading-tight"
      >
        {options.map((option) => (
          <option
            key={option.value}
            value={option.value}
            data-label={option.label}
          >
            {option.label}
          </option>
        ))}
      </select>
      <div className="pointer-events-none absolute top-10 right-0 flex items-center px-2 text-primaryDark">
        <svg
          fill="none"
          viewBox="0 0 24 24"
          strokeWidth={2}
          stroke="currentColor"
          className="w-6 h-6"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            d="M19.5 8.25l-7.5 7.5-7.5-7.5"
          />
        </svg>
      </div>
    </div>
  );
};

export default Dropdown;