0

I want to implement a promise in my code to run angular.bootstrap() in block 2 if 3 seconds has passed and angular.bootstrap() in block 1 has not been done, but only if.

I have two blocks of code:

// block 1:
Office.initialize = function (reason) {
    $(document).ready(function () {
        angular.bootstrap(document, ['myApp'])
    })
}

// block 2:
$(document).ready(function () {
    angular.bootstrap(document, ['myApp'])
})

Does anyone know how to do this?

Edit 1: Just to clarify that it is possible that Office.initialize is never executed (ie, when the app is loaded in Office as an add-in). In this case, I still want to execute angular.bootstrap of block 2 in 3 seconds.

SoftTimur
  • 5,630
  • 38
  • 140
  • 292
  • 1
    This really sounds like an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Why would you need two different calls to bootstrap in the first place? Also no need to wrap `angular ready` inside jQuery ready – charlietfl Jul 09 '17 at 01:50
  • [Here](https://stackoverflow.com/q/44989152/702977) is why I need two different calls... – SoftTimur Jul 09 '17 at 01:52
  • @charlietfl I just removed `angular ready` to simply the code, thank you... – SoftTimur Jul 09 '17 at 02:01

2 Answers2

1

You can use the setTimeout() and clearTimeout() functions in JavaScript.

Function usage:

setTimeout :

setTimeout(function, time);`
//function is the function to execute
//time is the duration to wait (in milisecods) before executing the function

clearTimeout :

clearTimeout(id);`
//id is the id of the setTimeout block to stop from executing

This is how you would implement the functions into your code:

// block 1:
var wait = setTimeout(myFunction, 3000);
Office.initialize = function (reason) {
  $(document).ready(function () {
      angular.element(document).ready(function () {
          angular.bootstrap(document, ['myApp'])
          clearTimeout(wait);
      })
  })
}

// block 2:
function myFunction() {
  angular.element(document).ready(function () {
      angular.bootstrap(document, ['myApp'])
}
user2864740
  • 60,010
  • 15
  • 145
  • 220
cyn
  • 3,509
  • 2
  • 14
  • 19
  • Thank you... But it is possible that `Office.initialize` is never executed (when the program is loaded in Office). In this case, I still want `angular.bootstrap` of `block 2` executes in 3 seconds. – SoftTimur Jul 09 '17 at 02:11
  • Yes. To fix that issue, you can move the `let wait = setTimeout(myFunction(), 3000);` statement to the line right before `Office.initialize` in block one There, it is implemented in the answer now. – cyn Jul 09 '17 at 02:13
  • (please use `var` rather than `let`)... It is odd, I just implemented this, but it seems that `myFunction` will **always** be executed **immediately**. – SoftTimur Jul 09 '17 at 02:23
  • 1
    It should be `setTimeout(myFunction, 3000);` without the parens after `myFunction`. – jfriend00 Jul 09 '17 at 02:27
  • @jfriend00 Actually, not exactly. It works with and without the parentheses at the end, so it is just a matter of preference. I use them because it looks neater because just saying myFunction would look like calling.... a variable... So, it works both ways, not should or should-not – cyn Jul 09 '17 at 02:30
  • @SoftTimur I am not sure why this does not work, as I have used the the setTimeout function multiple times. I will further look into this though. – cyn Jul 09 '17 at 02:33
  • 1
    With the parens, it calls the function IMMEDIATELY and then passes the return value from that to the timer. It does not wait for the timer which defeats the entire purpose. `setTimeout()` expects you to pass it a function reference. Passing it `myFunction()` executes that function immediately and passed `setTimeout()` the result of executing that function. This is a common mistake in Javascript. Only use parens after a function name when you want to execute it immediately. If you are just passing a function reference so it can be executed later, do not use parens after it. – jfriend00 Jul 09 '17 at 02:58
  • Hmm, I did not know that! Thanks =D – cyn Jul 09 '17 at 06:11
0

This solution uses underscorejs once function. Write a function like,

var bootstrapInit = _.once(function(){
angular.bootstrap(document, ['myApp']);
});

Now, you can call this function in block 1, block 2 and setTimeout with 3 sec. Whichever invokes this first will execute the function and the remaining call will be dummy one.

Ravindran
  • 82
  • 1
  • 3