0

I am a beginner to Python's Flask. I have a react native app. Amidst executing the main function, I want to get a user input. I also want to update the value of a status state hook dynamically amidst the function execution.

Here is what I have did.

Client device

React.useEffect(()=>{
    //all variables and hooks have been declared in original code
    //skipping all declarations to reduce size
    fetch('http://localhost:5000/start', {
            method: 'POST',
            headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                session: sessionID,
                url: url,
                user: username,
                password: password,
                stuff1: stuff1,
                stuff2: stuff2
            })
      });
      return unsubscribe;
    }, [navigation]);
});
//refresh the status every 2 seconds
React.useEffect(() => {
    const interval = setInterval(() => {
        fetch('http://localhost:5000/status',{
            method: 'POST',
            headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                session: sessionID
            })
    }).then(res => res.json()).then((data)=>{
        setStatus(data.status);
        console.log(data.status);
        if(data.status==='Failed'){
            setStatus("Sorry, this task has failed");
            setTimeout(()=>{navigation.goBack()}, 3000)
        } 
    }).catch(()=>{
        setStatus("Either our server or this device went offline");
        //just giving user 5 secs to read the status
        setTimeout(()=>{
            setStatus("Try again...")
            navigation.goBack('Task_Elaborate');
            return;
        }, 5000)
    });
    }, 2000);
    return () => clearInterval(interval);
}, []);

Server (running Flask)

#function to refresh status in client device
@app.route('/status', methods=['GET','POST'])
@cross_origin(origin='*',headers=['Content-Type','Authorization'])
def refresh_status():
  data = request.get_json()
  session['currentuser'] = data['session']
  if(stuff.status=='Failed'):
    session.pop(data['session'], None)
  return jsonify({'status':stuff.status})

#function to run for triggering main()
@app.route('/start', methods=['GET', 'POST'])
@cross_origin(origin='*',headers=['Content-Type','Authorization'])
def start_main():
  data = request.get_json()
  url = data['url']
  username = data['user']
  password = data['password']
  stuff1 = data['stuff1']
  stuff2 = data['stuff2']
  session['currentuser'] = data['session']
  stuff.main(url, username, password, stuff1, stuff2)
  return ""

When stuff.main() runs, I want to get a user input and use that for further processing. How can I do that?

As for the status, the app first starts off the main function by making a request to the server. This triggers the execution of the main() in server. Then, the app makes requests for refreshing the status every 2 seconds. These code snippets do work. But I expect a medium-high crowd of users and this will slow it down. Speed is a very important aspect of this app due to what it is doing mainly. Also, in this method, I can't get the user input, which is the essential part of this question.

Vishal DS
  • 175
  • 5
  • 16
  • Why send the exact same data to the server every two seconds when you can simply do it after it changes on the client? Why not 1) wait for user input in react native then 2) send the update to the server? –  Aug 30 '20 at 09:20
  • I didn't get that one correctly. I'm sending session ID to the server to get the corresponding value of `status` variable which is generated at server. Also, as for user input, `stuff.main()` will require the input data after it runs for a while and only if it satisfies many conditions. And, I don't know how to "update" as I'm new to Flask. So if we keep waiting for user input in react native, if `main()` doesn't need it, then what will we do? Also, the user input is a randomly generated value which is generated due to execution of `main()` (like an OTP). I hope I have made this clear... – Vishal DS Aug 30 '20 at 15:26
  • Also, how can I change `status` after it changes on the client without repeating the request every 2 seconds? Can you please share any links/articles etc that might help? I knew that this is a bad approach in the first place, but don't know any alternatives. – Vishal DS Aug 30 '20 at 15:36
  • I have no idea what your app is doing, is it simply requesting the current status from the server? Does that status change for a user without them doing anything? I also don't understand your requirement at all. Where (when) exactly do you want user input? "in the midst" of what? React is not really a real-time framework, it is primarily event based. –  Aug 30 '20 at 17:40
  • Yes the status changes without the user doing anything. In the midst of `stuff.main()`, I need a user input. – Vishal DS Sep 01 '20 at 07:20
  • You mean you want to send a request from the server to the app that displays a prompt to the user, then wait for the user to enter something, then send back the result to the server and continue the function...? Why? This is beginning to sound like an [xy problem](http://xyproblem.info/). I don't think I can help you with this. –  Sep 01 '20 at 07:45
  • Yes that is exactly what I want to do... If you can't help, it's okay. I'll do it using websockets. Just wanted to know if I could use Flask for doing this – Vishal DS Sep 01 '20 at 07:48
  • You need websockets for real-time communication, but you'll also need a main backend; just use flask *and* websockets. What I still don't understand is why you're asking the user for information in the midst of `main`; why not ask them when they open the app, then send the result to the server? Are you asking them something that relates to the current server state? And even if so, there should be no need to do it while a flask app route function is running (and I don't think it's possible to begin with) –  Sep 01 '20 at 07:50
  • The value needed as user input is a randomly generated key in this app. Like an OTP recieved via SMS to the user. It is generated as a result of executing main. How can I ask it beforehand? – Vishal DS Sep 01 '20 at 07:52
  • Wait, so main is generating the value, then asking the user for it...? Regardless, I think the better approach is to run main without the value, show the prompt, then run main again after the user sends the reply. I still think this is an xy problem, but I don't know how your app is supposed to work so I have to guess wildly. –  Sep 01 '20 at 08:02

0 Answers0