PaulusfranCircus
PaulusfranCircus

Reputation: 1

Call function within another in Javascript

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().

Upvotes: 0

Views: 142

Answers (2)

VLAZ
VLAZ

Reputation: 29086

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).

Upvotes: 0

charlietfl
charlietfl

Reputation: 171690

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);
 }....... 

Upvotes: 1

Related Questions