0

I've the following script:

gapi.analytics.ready(function() {
  viewSelector.on('viewChange', function update (data) {
  var title = document.getElementById('view-name');
  title.innerHTML = data.property.name + ' (' + data.view.name + ')';

  activeUsers.set(data).execute();
  renderWeekOverWeekChart(data.ids);
  renderTopBrowsersChart(data.ids);
  renderTopCountriesChart(data.ids);

  setTimeout(function() {
    var list = document.getElementsByTagName("tr")[0];
    list.getElementsByTagName("th")[0].innerHTML = "Pagina's";
    list.getElementsByTagName("th")[1].innerHTML = "Paginaweergaven";
  }, 500); 
 });
});

And within the following code I would like to re-run the update(); function.

function datumwissel( datumbtn ) {
 if ( datumbtn.className == 'maand' ) {
    datumbtn.className = 'jaar';
    dimensions1 =  'ga:month,ga:nthMonth';
    start1 = moment(now).date(1).month(0).format('YYYY-MM-DD');
    end1 = moment(now).format('YYYY-MM-DD');
    start2 = moment(now).subtract(1, 'year').date(1).month(0).format('YYYY-MM-DD');
    end2 = moment(now).date(1).month(0).subtract(1, 'day').format('YYYY-MM-DD');
    format1 = 'M';
    format2 = 'MMM';
    update();
 } 
 else {
    datumbtn.className = 'maand';
    dimensions1 =  'ga:date,ga:nthWeek';
    start1 = moment(now).subtract(2, 'day').date(1).format('YYYY-MM-DD');
    end1 = moment(now).format('YYYY-MM-DD');
    start2 = moment(now).subtract(2, 'day').date(1).subtract(1, 'month').format('YYYY-MM-DD');
    end2 = moment(now).subtract(2, 'day').date(1).subtract(1, 'day').format('YYYY-MM-DD');
    format1 = 'YYYYMMDD';
    format2 = 'Do';
    update();
  }
 }  

But somehow this doesn't work. I also tried in the above script: window.update = function (data) {}. But that also doesn't work.

How can I call the update(); function that is situated inside the gapi.analytics.ready(function() {} ?

Important is that I cannot make it globally as it has to be situated inside the gapi.analytics.ready().

1
  • 2
    You can't just pull the code out into a function that's available to both bits of code? Commented Jul 21, 2016 at 16:34

2 Answers 2

1

It's really a simple matter of moving the function declaration

function update (data) {
  // same as existing code
}

gapi.analytics.ready(function() {
  viewSelector.on('viewChange', update );
});

And passing in data needed when you call it in your other function

function datumwissel( datumbtn ) {
 if ( datumbtn.className == 'maand' ) {
    ..........

    update(datumbtn);
 }....... 
1
  • Thanks for your help! I tried this but then the problem moves to the next bit of code: activeUsers.set(data).execute(); renderWeekOverWeekChart(data.ids); renderTopBrowsersChart(data.ids); renderTopCountriesChart(data.ids); Commented Jul 22, 2016 at 5:27
0

Important is that I cannot make it globally as it has to be situated inside the gapi.analytics.ready()

That's not actually true - you can have it global and there at the same time. Whether you want to, is a different manner, as that would pollute the global namespace and so on. However, here is how that can be achieved:

First, extract the update function outside of the ready handler like so

function update (data) {
  var title = document.getElementById('view-name');
  title.innerHTML = data.property.name + ' (' + data.view.name + ')';

  activeUsers.set(data).execute();
  renderWeekOverWeekChart(data.ids);
  renderTopBrowsersChart(data.ids);
  renderTopCountriesChart(data.ids);

  setTimeout(function() {
    var list = document.getElementsByTagName("tr")[0];
    list.getElementsByTagName("th")[0].innerHTML = "Pagina's";
    list.getElementsByTagName("th")[1].innerHTML = "Paginaweergaven";
  }, 500); 
 }

This will create a new function with the name update which accepts one parameter called data. Thanks to hoisting it would not matter if it's before or after anywhere you want to use it, as it would be effectively "pulled" to the top.

Next, you can just use the function inside the ready handler like so:

gapi.analytics.ready(function() {
  viewSelector.on('viewChange', update);
});

Since .on(events, handler) accepts a function as the second parameter, you can just provide a function reference there. It doesn't matter that your function is technically declared elsewhere, as it is still going to be called with the same arguments. Similarly, if you replace update with alert you will be giving the reference to window.alert so you will get an alert with data.

With that, you can just call the same function in your other piece of code.

That is true for any place that uses callbacks, including setTimeout - you can just give a function reference and it's going to be called. Internally, those kinds of functions almost always do something like callback() or callback(someData), occasionally callback.call(/* parameters */) where callback is the passed in argument. Whether you define that argument as you are calling the function, e.g., selector.on("click", function() {/* code */}) or separately, e.g.,

function clickHandler() { /* code */ }
selector.on("click", clickHandler)

matters little.

With that said, whether you want the function global is a different matter. Unless both pieces of code are in the same place, a global function may be the easiest way. You could, also, namespace anything your app uses, which would partially avoid the global pollution. Not completely, but sometimes you just need to have things living under window if you have multiple files, in which case, you can define your own little corner there to play with: window.myApp = window.myApp || {} would create a new object that can serve as namespace and so you will be able to do things like myApp.update = function(data) { /* code */ } and thus share that code.

If your two pieces of code are indeed in one file, then you merely need to create the function outside both using var update = function(data) { /* code */ } then hand it to each in the exact same way, since update is still going to be a function reference, however, if assigned to a variable, it won't be added to the global namespace (nor would the declaration be hoisted).

1
  • Thank you so much for your explanation! It helped me understand it better. However, the problem now moves to the next bit of code: activeUsers.set(data).execute(); renderWeekOverWeekChart(data.ids); renderTopBrowsersChart(data.ids); renderTopCountriesChart(data.ids); Now it says that this isn't defined as these functions are within the gapi.analytics.ready Commented Jul 22, 2016 at 5:28

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.