So, for a school project, we've been asked to make a website using flask. It's a website that has a group of pages , and each page contains a simple mini game (such as rock, paper, scissors; Guess the number, etc). The thing is - all of the minigame's logic must be handled in the backend with flask so we can practice python's oop...
#🔒 flask with javascript ( )
111 messages · Page 1 of 1 (latest)
@buoyant isle
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
Closes after a period of inactivity, or when you send !close.
but for the sake of visual appeal, I don't want the page refreshing every time the user interacts with an element, so I'm using js on some parts, and I only refresh the page on crucial moments
the thing is, the js code needs to communicate with the server via an api call ( that I'm making with fetch)
but I read somewhere that if a route receives a request from the js code, it will return the data to the js code that made the call, and that's why you need to handle it with something called promise
Is there a way to make so that the redirect is sent direct to the browser instead of sending it to the js code?
I'm not sure what you mean by this last line.
sorry, I edited message above it
I'm still not sure what you mean.
If you want to avoid refreshing the page though, you'd do that via Javascript. You don't actually ever need to refresh the page if you handle everything via JS.
in that case, the js is sending a post request to the server, the server validates the data, and then re renders the page with the new information
[I didn't respond because it seemed like you were typing something]
yea ik
but the restriction is that I needed to use flask's jinja to return dinamic html
so I kinda of mixed js in some parts, and jina in others
for an example, in my rock paper scissors minigame
Technically, you can do that without refreshing the page by having the server respond with HTML, and then using container.innerHTML = responseHtml on the frontend in JS. That has problems though and generally is not how you should approach that problem.
The server should ideally just respond with raw data, then the frontend can plug that data into existing HTML
I made the selectors in js , the js sends the choice to the server, the server validates if it's a valid choice, then return the result refreshing the page( you could just do this entirely on js instead of refreshing the page, but yea need to use jinja somewhere on the code so )
yea, that's a definitely better approach
not the inner html thing, the last one
I think I'll make it the way you said, then I'll talk to my teacher to see if he accepts
it seems more logic to me
Ya, that's how it's typically done. innerHtml is bad for this. I only suggested it because it satisfies both requirements of responding with HTML and not refreshing the page.
yea, the page is gonna refresh in some point or another, but that's a great tip to minimise that problem
but I have another question
Well, like I mentioned, you don't ever actually need to refresh. At work, our entire app is a Single Page Application. Users submit forms and navigate without ever reloading the page.
I didn't understood session storage and fetch fully, the js code is running on the client side right? So what is the "scope" of session storage? Like, the server is the one serving the html with the js file on each route, but if I save a value in session storage, do other scripts be able to acess him? Eg. in a /hangman-game route I save to session storage a value like "player-choice:'a' ", and I go to another route /guess-the-number that has a different js file. Would sessionStorage.get("player-choice") return anything? Is session storage per web-page or per browser session ( or none of the options idk)?
I'll be honest, I don't think I've ever actually used session storage. We use Local Storage for basic data saving, and IndexedDB for more complex data.
The JS is running on the client computer, yes. And for all types of storage, your entire site can access the data. It doesn't matter what page you're on (In simple cases. In more complex cases, it may matter).
now that you said that, I'm starting to think that I may have overthought the process
for a simple thing such as a string
Local Storage is basically the same thing as Session Storage. Local Storage is just available accross all tabs, and the data lives for longer.
botoes_escolha.forEach(function(botao){
botao.addEventListener('click',function(){
setar_escolha(botao);
/*Guardando informação da escolha na sessão ativa ( post request ira manda-la para a aplicação python) */
sessionStorage.setItem("escolha_player",botao.dataset.escolha)
/* above it saves the choice on a session storage */
})
})
that's something I was worried about
but it's not a data that needs to persist across tabs
the player chooses an option
it saves the value for later - when the player clicks another button to start the game
simple as that
If you only want the data in a single tab, and it's ok if closing the tab destroys the data, Session Storage is appropriate.
I think I can even save it on a simple variable? or is it a bad practice
idk if it even works, didn't tried that
Yes, you can also just save the data in JS. That data will be lost when the page refreshes, though, so you'd need to store it somewhere to persist it. We store a ton of data inside variables in JS, but our page also doesn't refresh, so the data lives in JS for the entire time the user uses the app in many cases.
makes sense
but in this case I think I'll keep it in the session storage, I don't need to save much data
and now that I know that the data is only persistent in the current tab, there isn't the risk of mr accidently setting a value that has the same key in an other route and changing the value to the one in the current route
I don't think that that's really a concern unless the user was playing multiple instances of the same game across tabs.
Which, in theory, they could do, but idk why they would.
but in this case it would be just like a copy of the other instance?
in session storage data
or a change in a tab affect the other one?
I meant if they had rock-paper-scissors open in two tabs and were playing two games at once, ya, the games could interfere with each other if they were using Local Storage. It would be weird to play the same game at the same time in different tabs, though.
With session storage, one tab won't be able to see data from another tab, so there isn't the possibility for them interferring with each other.
alr
so I'll go with session storage in this case
but maybe I'll have to use local storage at some point
that cleared one of the questions
now the one that is bugging me out
the fetch one
What about it?
the promise thing
fetch(URL_ALVO,{
method:'POST',
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({escolha_player : sessionStorage.getItem("escolha_player")})
}).then(response => {
if (response.redirected) {
window.location.href = response.url;
} else {
}
});
every type of request that I make with fetch is gonna return a promise right?
or it depends of the type of request make?
Well, fetch itself returns a Promise.
Afaik, it always returns a Promise. Since we use Angular at work, we actually use Angular's HttpClient instead of fetch, so I'm not super familair with it.
But HttpClient always returns a Promise
Any IO task in JS will return a promise, or expect a callback.
in this case the callback is the server's response after receiving the request
so in this case, if in flask i use return redirect(url_for('jokenpo')) after receiving the request
A callback would be if fetch accepted a function instead of returning a promise, and called that function when fetch got a response.
the callback value is gonna be this redirect object? how is that possible
may you give an example?
If fetch accepted a callback, that would look something like:
const data = { // For cleanliness
method:'POST',
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({escolha_player : sessionStorage.getItem("escolha_player")})
};
fetch(URL_ALVO, data, response => {
if (response.redirected) {
window.location.href = response.url;
} else {
}
});
It looks similar since then also takes a function, but it's a bit different.
The modern way of using promises is actually to use await/async syntax:
async function someFunction() {
const data = { // For cleanliness
method:'POST',
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({escolha_player : sessionStorage.getItem("escolha_player")})
};
const response = await fetch(URL_ALVO, data);
if (response.redirected) {
window.location.href = response.url;
} else {
}
}
Sorry, I forgot to use data in my last example
I just realized that.
Notice how with await, you don't need to nest code inside of then .
Is this syntactic sugar or does this really interferes on how the response is received? Idk much about async functions, but from what I understood in the code, you created an async function, and used await to yield until the fetch returns the data, after that you check the response content in a synchronous way
someFunction is async just as fetch is, but in this case you yield for fetch
Afaik, it's just sugar. It doesn't really matter beyond that unless you're really interested in the deep lore of JS.
But yes, the rest of your comment is basically right.
await basically gives up control so other code that was previously waiting on await can get a turn to execute.
This really shines when you have sequential calls that need to happen one after the other:
async function someFunction() {
const data = { // For cleanliness
method:'POST',
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({escolha_player : sessionStorage.getItem("escolha_player")})
};
const response = await fetch(URL_ALVO, data);
// Then a second fetch that may use data returned from the first fetch
const responseTwo = await fetch(URL_ALVO, data);
// Use response data
}
This would get increasingly messy with then.
(also exceptions are propagated correctly iirc)
Ya, it makes error handling a lot easier to deal with
with then you would just put .then after .then?
.then().then().then()
what
Ya. Not terrible, but it's nicer.
The bot interprets text starting in . as a command.
yea it doesn't seem nice
alr that clears up the question I had
I was stuck at this because I was returning render_template in my flask and didn't understood why the page wasn't refreshing
didn't even knew that promises were a thing
Just a heads up, since this question was almost entirely JS-based, it's arguably offtopic. You may get shut down if you ask a similr question here in the future. Just so you know.
yea, I kinda run out of the topic
the original question was supposed to be that one
but yea
It kinda answered the question
because I didn't knew that my flask code was sending the data to the js, not the browser directly
thanks for the help 🙏 🙏
You're welcome. If you done with the thread, you can close it with !close.
really appreciate the patience
alr
Np
This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.