Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

128
Visualizações
Bar Chart Renders Before Receiving Updated Data

I have a simple issue relating to function sequence that I'm struggling to solve on my own. Essentially, I'm rendering a bar chart based on parameters selected by the user. This works perfectly on the first go, but when the user updates their parameter selection and hits "render" again, the chart doesn't update. It's only on the second button click that the chart renders with updated data.

I can see in the console that the "generate chart" function IS receiving the updated data, so I know the issue is that the chart is rendering before the new data is loaded. I understand that the common solution to this type of problem would be using JS Promises or callbacks, but I can't figure out how to execute it, and would really appreciate some help.

Here's the code structure. I have to make two API calls to get the data.

const ajaxCallOne = () => {
    // Make API call for first data set (data1). On success, invoke the next API call, passing data1.
    success: (data1) => {
        ajaxCallTwo(data1);
    }
}

const ajaxCallTwo = (data1) => {
    // Make second API call for another set of data ('data2'). On success, invoke a function to visualize all the data in a bar chart, passing it both data1 and data2.
    success: (data2) => {
        populateBarChart(data1, data2)
    }
}

const populateBarChart = (data1, data2) => {
    // Function to create a bar chart and populate it with data1 and data2 from the API calls

    // The data retrieved from the API calls is based on parameters selected by the user. When the user selects new parameters and hits the "view results" button again, we kick off another round of API calls, which pass the new data to this populateBarChart function.

    // I am using ApexCharts.js library to render the bar chart. The syntax for actually rendering the chart looks like this:
    let chart = new ApexCharts(
      document.querySelector("#audience-reach-chart-container"),
      options
    );

    chart.render();
}

At first I thought I needed to destroy / empty out the chart at the beginning of the function, but since the function creates a new instance of the chart every time it's invoked, there's nothing to target and destroy.

Also, when I console.log the data being received by the populateBarChart function, I can see the updated data is being received. So the issue must be that the chart is rendering based on the old data, and I need to control the sequence of events?

I can't figure out how to go about this within the code design. Any insights would be greatly appreciated.

about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

You're absolutely right that this can be solved using callbacks, promises and even async/await.

However, this problem statement may have a nuance e.g. if you're using <select> dropdowns, the event listener registered on them could be slightly incorrect. OR, if the ApexCharts library's behavior is to withhold rendering for some reason, then it'll be hard to say so without going through the documentation. Hence, an example on codesandbox or jsfiddle can help us.

Let's look at one possible solution - Ideally, when using promises, we should do something like this:

let container = document.querySelector("#audience-reach-chart-container");

const ajaxCallOne = () => {
    // Make API call for first data set (data1).
    // No need to invoke the next API call. Just ensure it returns a promise object
}

const ajaxCallTwo = () => {
    // Make second API call for another set of data ('data2').
    // Sit still! No need to do anything here as long as this function returns a promise
}

// Run this when the user hits 'render' button
Promise.all([ajaxCallOne, ajaxCallTwo]).then((values) => {
  console.log(values);
  // values[0] holds data1
  // values[1] holds data2
  let options = doSomethingOnThese(values[0], values[1]);

  // Populate the BarChart here
  let chart = new ApexCharts(container, options);
  chart.render();
});

I've created a sample app(https://codesandbox.io/s/unruffled-cookies-tbcerp?file=/src/index.js) to mimic your usecase here:

// https://codesandbox.io/s/unruffled-cookies-tbcerp?file=/src/index.js
(async function () {
  var options = {
    chart: {
      height: 350,
      type: "bar"
    },
    dataLabels: {
      enabled: false
    },
    series: [],
    title: {
      text: "Ajax Example"
    },
    noData: {
      text: "Loading..."
    }
  };

  var chart = new ApexCharts(document.querySelector("#chart"), options);

  chart.render();
  try {
    const ajaxCallOne = await fetch(
      "https://my-json-server.typicode.com/apexcharts/apexcharts.js/yearly"
    );

    const ajaxCallTwo = await fetch(
      "https://my-json-server.typicode.com/apexcharts/apexcharts.js/yearly2"
    );
    let data1 = await ajaxCallOne.json();
    let data2 = await ajaxCallTwo.json();
    console.log(data1, data2);
    chart.updateSeries([
      {
        name: "Sales",
        data: data1
      },
      {
        name: "Sales2",
        data: data2
      }
    ]);
  } catch (e) {
    console.log(e);
  }
})();
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda