0

I would like to use a function then return a value back. This function was written in a script in an external Javascript called "tools_4.js".

Here ist the code of the tools_4.js:

function sendIso3Info(inCurrency) {
  let iso3Info = {
    'text': inCurrency,
  }

  einenWert = 'Hallo';

  fetch(`/processIso3Info/${JSON.stringify(iso3Info)}`)
    .then(function(response) {
      return response.text();
    })
    .then(function(text) {
      console.log('GET response text:');
      einenWert = text;
      console.log('This is the value in the fetch')
      console.log(einenWert);

    })
    .then(function(text) {
      data_function(einenWert); //calling and passing to another function data_function
    })

  //another functions
  function data_function(data) {
    console.log('ich bin in der neuen Funkion!');
    alert(data);
    temp = data;
    console.log(temp);
  }

  console.log('Value outside of the function');
  console.log(temp);

  return temp;
}

I was using the fetch-function to become the value. But I can not use the variable "temp", because it's written "undefined". I was trying with a global variable, but it doesn't work?

here is the code of the app.py:

########  imports  ##########
from flask import Flask, jsonify, request, render_template
import currencys
import json

app = Flask(__name__)


@app.route('/')
def home_page():
    example_embed='This string is from python'
    return render_template('index.html', embed=example_embed)

    
######## Data fetch ############
@app.route('/processIso3Info/<string:iso3Info>', methods=['GET','POST'])
def processIso3(iso3Info): 
    if request.method == 'POST': # POST request
        print(request.get_text())  # parse as text
        return 'OK', 200
    else: # GET request
        iso3InfoCurrency = json.loads(iso3Info) 
        out = currencys.return_iso3(iso3InfoCurrency['text'])
    
        return out

app.run(debug=True)

and the code of the template:

<head>
    

</head>
    
<body>

    <h1> Python Fetch Example</h1>
    <p id='embed'>{{embed}}</p>
    <p id='mylog'/>
    <script type="text/javascript" src="{{ url_for('static', filename='tools_4.js') }} 
    </script>
    <script> 
        iso3Text = sendIso3Info('Euro');
    </script>
    
<body>

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • This might help with understanding callbacks: https://felix-kling.de/blog/2019/javascript-callbacks-misconceptions.html Also see [How to return the response from an asynchronous call](https://stackoverflow.com/q/14220321/218196) – Felix Kling Sep 10 '21 at 09:55

1 Answers1

0

You're obviously confused by asynchronus code execution. Let's clarify what happen :


function sendIso3Info(inCurrency) {
  
  let iso3Info = {
      'text': inCurrency,
  }
  einenWert = 'Hallo';
 
  //1) there, the code will not stop it's execution.
  //A fetch request takes ages at computer time scale to execute. So the code execution
  //will not stop there.
  fetch(`/processIso3Info/${JSON.stringify(iso3Info)}`)
      .then(function (response) {
        //3) the promise resolve
        return response.text();
      }).then(function (text) {
        //4 that other promise resolve
        console.log('GET response text:');
        einenWert = text; 
        console.log('This is the value in the fetch')
        console.log(einenWert);
        
      }).then(
        //5 Then, this one.
        function(text){
        //you call finaly your function
        data_function(einenWert); //calling and passing to another function data_function
      })

  //another functions
  function data_function(data){
    //6 even if you assing something to temp, the sendIso3Info already returned
    //ages ago.
    console.log('ich bin in der neuen Funkion!');
    alert(data); 
    temp = data;
    console.log(temp);
  }

  //2) So, when you get there, temp is still undefined since fetch() can't resolve as fast. Your function will return before the fetch resolves.
  console.log('Value outside of the function');
  console.log(temp); 
  return temp;
}

Now, how to solve your problem ?

There are some ways to do it.

The esaier is to use asyncfunctions :


async function sendIso3Info(inCurrency) {
  
  let iso3Info = {
      'text': inCurrency,
  }
 
  //Since we are in an async function, we can explicitly await for other asynchronous call to resolve
  const response = await fetch(`/processIso3Info/${JSON.stringify(iso3Info)}`);
  return await response.text();
}

And to use your async function you can do as follow :


sendIso3Info('Euro').then(res => console.log(res));

//or

(async() => {
    console.log(await sendIso3Info('Euro'));
})();

Jordan Breton
  • 1,167
  • 10
  • 17