1

I'm having a problem with javascript code. I am trying to have dynamical chart, which will update on changing a select field with plotly.reshape function. I call an Ajax request based function inside of chart() function and i want it to wait for variable assignment and then draw a chart. I think i'm using async/await in a wrong place. Can u guys help me ? It is my very first js script, but i need it in project.

function chart(){
  var x = Chart();
  var X =x[0];
  var Close=x[1];
  var High=x[2];
  var Low=x[3];
  var Open=x[4];
  console.log(X);
  var trace1 = {
    x: X, 
    close: Close, 
    decreasing: {line: {color: '#7F7F7F'}}, 
    high: High,
    increasing: {line: {color: '#17BECF'}}, 
    line: {color: 'rgba(31,119,180,1)'}, 
    low:  Low, 
    open: Open, 
    type: 'ohlc', 
    xaxis: 'x', 
    yaxis: 'y'
  };
  var data = [trace1];
  var layout = {
    ...
  };
  
  Plotly.newPlot('chart', data, layout);
  
}


 function Chart(){

  var data, date = [], price = [], open=[], Timestamp=[], High=[], Low = [];
  let selectedItem = document.getElementById('currency-selector').value;
  var url = `http://127.0.0.1:8000/${selectedItem}/`; 
  var x = new Array()
  var requestURL = url; //URL of the JSON data
  var request = new XMLHttpRequest({mozSystem: true}); // create http request  
  request.onreadystatechange = async function() {
   if(request.readyState == 4 && request.status == 200) {
      
      data = JSON.parse(request.responseText);
      
      for (var i=0; i<data.length;i++) {
          date.push(data[i].date)
          price.push(data[i].close);
          High.push(data[i].high);
          open.push(data[i].Open);
          Low.push(data[i].low);
          
      }
      
      //chart(date,price,High,Low,open);   
    }
  
  await request.open('GET', requestURL, true);
  request.send(); // send the request
  
}
  return [date,price,High,Low,open];
  }

1 Answers1

0

I can't test this because of the set up, but this should work... and return things in the order you expect them to be.

this is using the fetch api, which is generally much cleaner than the xmlhttp request api.

but so you know, async is the label for the function that contains await. and .then() is how to order things in a callback like that... the value that is awaited will execute each then first before returning the awaited value.

 async function Chart(){

  let date = [], price = [], open=[], Timestamp=[], High=[], Low = [];
  let selectedItem = document.getElementById('currency-selector').value;
  let url = `http://127.0.0.1:8000/${selectedItem}/`; 
  let requestURL = url; //URL of the JSON data
    return await fetch(requestURL)
    .then(res=>res.json())
    .then(data=>{
       data.forEach(x=>{
         date.push(x.date)
         price.push(x.close);
         High.push(x.high);
         open.push(x.Open);
         Low.push(x.low);
      })
   })
   .then(()=>{
      return [date,price,High,Low,open];
    })
 }

altruios
  • 986
  • 1
  • 10
  • 29
  • Now instead of arrays, like before, x = Chart(), returns promise of value, and values like x[1], x[2] are undefined. How can i get this to work ? – Bartosz Bicki Oct 23 '20 at 17:16
  • try let rVal = await fetch(requestURL) and return rVal on the next line... but more than that, make sure the execution is going in the right order. console.log("1"), "2", etc - if you sprinkle those in, a console.log above let data should be first, then the next scope is the .then()'s. and last should be the bottom of Chart. promises resolve to their values, it's just making sure it's fully resolved before you exit scope from Chart(). – altruios Oct 23 '20 at 18:53