1

I have to use list of accounts as labels in my chart. In order to fetch list of records I have used js remoting. I am able to fetch but not use within chart.js labels.

Here goes my vfp :-

    <apex:page Controller="AccountRemoter">
   <apex:includeScript value="{!$Resource.jquery}"/>
    <apex:includeScript value="{!$Resource.chartLibrary}"/>


 <canvas id="myChart" width="400" height="400"></canvas>
  <script>
  var names=[];
  Visualforce.remoting.Manager.invokeAction(
    '{!$RemoteAction.AccountRemoter.getAccountList}',        
    function(result, event) {
        var test = result;

      console.log(test);
        for (var i = 0; i< result.length ; i++){
        names.push(test[i].Name);
        }
    console.log(names[0]); // getting account
    });

   var ctx = document.getElementById("myChart");

  //** in this chart method I want to use names[0] and so on... **

 var myChart = new Chart(ctx, {
 type: 'bar',
 data: {
  labels: [names[0],names[1],names[2],names[3],names[4],names[5],names[6]],
  datasets: [{
  label: 'No. Of Contacts in each account',
  data: [12, 19, 3, 5, 2, 3, 20],
  backgroundColor: [
    'rgba(255, 99, 132, 0.2)',
    'rgba(54, 162, 235, 0.2)',
    'rgba(255, 206, 86, 0.2)',
    'rgba(75, 192, 192, 0.2)',
    'rgba(153, 102, 255, 0.2)',
    'rgba(255, 159, 64, 0.2)',
    'rgba(255, 99, 132, 0.2)'
  ]
  }]
   },
  options: {
  responsive: false,
  scales: {
  xAxes: [{
    ticks: {
      maxRotation: 90,
      minRotation: 80
    }
  }],
  yAxes: [{
    ticks: {
      beginAtZero: true
    }
  }]
  }
 }
 });

Controller code is as follows:-

 global with sharing class AccountRemoter {

 @RemoteAction
    global static List<Account> getAccountList(){
      List<Account> accList=[select id,Name from account];
      return accList;
    }
}
2

Unlike Apex or Java , Javascript is non blocking language .Javascript has a concept of callback.Hence the code lines and execution need not necessarily be sequential .

Your Javascript remoting call is still under execution while the code for the charting is executed before that .

You will need to make sure that charting functions execute only after the visualforce remoting call from server returns response . Quick fix is below code which moves all script you have for chartJs inside javascript remoting callback like below .

Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.AccountRemoter.getAccountList}',  

function(result, event) {

    var test = result;
    var names=[];
    console.log(test);

    for (var i = 0; i< result.length ; i++){
      names.push(test[i].Name);
    }

    console.log(names[0]); // getting account

    var ctx = document.getElementById("myChart");

    var myChart = new Chart(ctx, {
      type: 'bar',
      data: {
          labels: [names[0],names[1],names[2],names[3],names[4],names[5],names[6]],
          datasets: [{
          label: 'No. Of Contacts in each account',
          data: [12, 19, 3, 5, 2, 3, 20],
          backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)',
            'rgba(75, 192, 192, 0.2)',
            'rgba(153, 102, 255, 0.2)',
            'rgba(255, 159, 64, 0.2)',
            'rgba(255, 99, 132, 0.2)'
            ]
            }]
        },
      options: {
        responsive: false,
        scales: {
          xAxes: [{
          ticks: {
            maxRotation: 90,
            minRotation: 80
          }
        }],
        yAxes: [{
          ticks: {
            beginAtZero: true
          }
        }]
      }
    }
  });

});

If you have more than one remoting call then you will run into callback hell that makes hard to maintain code. Would recommend using Javascript Promises for maintainability .

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.