#🔒 flask with javascript ( )

111 messages · Page 1 of 1 (latest)

buoyant isle
#

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...

cyan acornBOT
#

@buoyant isle

Python help channel opened

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.

buoyant isle
#

the thing is, the js code needs to communicate with the server via an api call ( that I'm making with fetch)

buoyant isle
#

Is there a way to make so that the redirect is sent direct to the browser instead of sending it to the js code?

heady cosmos
buoyant isle
heady cosmos
#

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.

buoyant isle
heady cosmos
#

[I didn't respond because it seemed like you were typing something]

buoyant isle
#

but the restriction is that I needed to use flask's jinja to return dinamic html

buoyant isle
#

for an example, in my rock paper scissors minigame

heady cosmos
#

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

buoyant isle
#

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 )

heady cosmos
buoyant isle
#

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

heady cosmos
#

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.

buoyant isle
#

but I have another question

heady cosmos
buoyant isle
# buoyant isle but I have another question

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)?

heady cosmos
#

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).

buoyant isle
#

for a simple thing such as a string

heady cosmos
#

Local Storage is basically the same thing as Session Storage. Local Storage is just available accross all tabs, and the data lives for longer.

buoyant isle
#
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 */
    })
})


buoyant isle
#

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

heady cosmos
#

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.

buoyant isle
#

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

heady cosmos
#

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.

buoyant isle
#

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

heady cosmos
#

Which, in theory, they could do, but idk why they would.

buoyant isle
#

in session storage data

#

or a change in a tab affect the other one?

heady cosmos
#

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.

heady cosmos
buoyant isle
#

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

heady cosmos
buoyant isle
#

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 {
          
        }
    });
heady cosmos
#

What about it?

#

What about the promises?

buoyant isle
#

every type of request that I make with fetch is gonna return a promise right?

#

or it depends of the type of request make?

heady cosmos
#

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.

buoyant isle
#

so in this case, if in flask i use return redirect(url_for('jokenpo')) after receiving the request

heady cosmos
#

A callback would be if fetch accepted a function instead of returning a promise, and called that function when fetch got a response.

buoyant isle
#

the callback value is gonna be this redirect object? how is that possible

heady cosmos
#

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 .

buoyant isle
#

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

heady cosmos
#

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.

torn wing
#

(also exceptions are propagated correctly iirc)

heady cosmos
#

Ya, it makes error handling a lot easier to deal with

buoyant isle
#

.then().then().then()

#

what

heady cosmos
#

Ya. Not terrible, but it's nicer.

heady cosmos
buoyant isle
#

ducky_concerned 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

heady cosmos
#

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.

buoyant isle
buoyant isle
#

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 🙏 🙏

heady cosmos
#

You're welcome. If you done with the thread, you can close it with !close.

buoyant isle
#

really appreciate the patience

heady cosmos
#

Np

buoyant isle
#

have a good night / good evening / good day

#

!close

cyan acornBOT
#
Python help channel closed with !close

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.