Reputation: 2316
Doing 2nd CS50 project and the first thing I have to do is to create an index.html page where I have to type in a username and it'll displayed. I have to do it using SocketIO to make other users be able to see it too.
When I run my Flask app and go the page I'm getting the following text in my console:
flask run
* Serving Flask-SocketIO app "main.py"
* Forcing debug mode on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 399-480-796
127.0.0.1 - - [2018-08-12 05:17:54] "GET / HTTP/1.1" 200 1123 0.008075
127.0.0.1 - - [2018-08-12 05:17:55] "GET /index.js HTTP/1.1" 404 342 0.000796
127.0.0.1 - - [2018-08-12 05:17:55] "GET /static/index.js HTTP/1.1" 404 342 0.000821
127.0.0.1 - - [2018-08-12 05:17:55] "GET /static/index.js HTTP/1.1" 404 342 0.003149
But when I press my "Enter" button it fails with 'Method Not Allowed' and what I see in my console is:
127.0.0.1 - - [2018-08-12 05:18:01] "POST / HTTP/1.1" 405 323 0.003737
project_folder/main.py:
from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config["SECRET_KEY"] = 'dev'
socketio = SocketIO(app)
@app.route("/")
def index():
return render_template("index.html")
@socketio.on("new user")
def new(data):
username = data["username"]
emit('plus user', {'username': username}, broadcast=True)
project_folder/templates/layout.html:
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
<script type='text/javascript' src='index.js'></script>
<script src='{{ url_for('static', filename='index.js') }}'></script>
</head>
<body>
<div class="container">
{% block body %}
{% endblock %}
</div>
</body>
</html>
project_folder/templates/index.html:
{% extends "layout.html" %}
{% block title %}
Sign In
{% endblock %}
{% block body %}
<form action="{{ url_for('index') }}" method='post'>
<h1>Hi! In this chat room you can be whoever you want.</h1>
<h2>The only thing I ask you is to tell me the name I'll be calling you.</h2>
<h3>You don't have to tell me your real name.</h3>
<h4>Enjoy.</h4>
<br>
<div class="form-group">
<input class="form-control" name='username' autofocus placeholder="Username">
</div>
<div class="formgroup">
<button id='newuser' class='btn btn-primary' data-new='username'>Enter</button>
</div>
<ul id="users"></ul>
</form>
{% endblock %}
project_folder/templates/index.js:
document.addEventListener('DOMContentLoaded', () => {
// connect to websocket
var socket = io.connect(location.protocol + '//' + document.domain + ":" + location.port);
// when connected, configure buttons
socket.on('connect', () => {
document.querySelector('#newuser').onclick = () => {
const username = newuser.dataset.new;
socket.emit('new user', {'username': username})
};
});
});
// When a new user has registered , add to the ul
socket.on('plus user', data => {
const li = document.createElement('li');
li.innerHTML = data.username;
document.querySelector('#users').append(li);
});
It's almost the same task and I took like 90% of the code from the lecture video but it doesn't wrong. What am I doing wrong?
Upvotes: 1
Views: 1693
Reputation: 543
In Layout.html
You are Routing Index.Js to wrong Folder, either replace static with template as done below
<script src='{{ url_for('templates', filename='index.js') }}'></script>
Or create a new folder static in the root directory,i.e. project_folder if you want to use:
<script src='{{ url_for('static', filename='index.js') }}'></script>
Generally the second way is preferred.
Upvotes: 1
Reputation: 133
Looks like your routing is at fault here. Your form is submitting to URL pattern of 'index' but your routing only handles the '/' route.
Change
@app.route("/")
to following in main.py:
@app.route("/index")
Upvotes: 0