-1

I have a global variable numberOfMessages that I want to immediately set to a particular number according to what a call to a solidity contract brings back. The call is made in the document.ready function when the page is loaded. However, the variable isn't changed outside this function.

My code is basically like this:

var numberOfMessages = 0 // declared outside any function, so should be global
$(document).ready(function () {
Message.deployed().then(function (contractInstance) {
    contractInstance.getNumberMessages.call().then(function (v) {
      numberOfMessages = v
      alert(numberOfMessages) // returns something other than 0
    })
  })
})
alert(numberOfMessages) // returns 0

How can I have a global variable that is set to what a function returns when the page is loaded?

ZhouW
  • 1,187
  • 3
  • 16
  • 39
  • 1
    The problem with the final `alert(numberOfMessages)` is that it runs *before* the document ready event, and before your `.then()`. You *are* setting the global variable in the inner function, but you don't show any other code that runs *after* that event. – nnnnnn Jul 10 '17 at 03:16

3 Answers3

2

Your final line is running outside of the promises' .then() async callback. This means the last line runs before document ready even fires and before your async call finishes.

Also, don't use alert() to test your code since prompts like that are usually blocking, meaning the halt code execution and can do weird things with async callbacks. Instead use console.log() and see the results in your browser's Javascript console (usually opened by hitting F12).

Soviut
  • 88,194
  • 49
  • 192
  • 260
-1

Try to remove

var numberOfMessages = 0

at first line. If you assign a value to a variable that has not been declared, it will automatically become a GLOBAL variable.

chu.tien
  • 1
  • 1
  • If you use `var` outside of functions (which the OP explicitly says they're doing) that makes the variable global. If they completely remove that line then they'll get an error on the final line when they try to `alert(numberOfMessages)` before the ready event. – nnnnnn Jul 10 '17 at 03:34
-1

According to several other similar questions I could say declare your variable as window.numberOfMessages = 0.

#3 window.a = 0;

This creates a property on the global object explicitly, using the window global that refers to the global object (on browsers; some non-browser environments have an equivalent global variable, such as global on NodeJS). As it's a normal property, you can delete it.

This property is enumerable, on IE8 and earlier, and on every other browser I've tried.

Above classification has posted by here and gives you an explanation of what is a global scope variable and global explicitly variable.

window.numberOfMessages = 0 // This creates a property on the global object explicitly
$(document).ready(function() {
  Message.deployed().then(function(contractInstance) {
    contractInstance.getNumberMessages.call().then(function(v) {
      window.numberOfMessages= v
      console.log(window.numberOfMessages) // returns something other than 0
    })
  })
})
console.log(window.numberOfMessages) // returns 0
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
CodeMonkey
  • 2,828
  • 1
  • 23
  • 32
  • Using `var` outside of a function creates a global variable. The OP's variable *is* global, they're just not allowing for the asynchronous nature of their code. – nnnnnn Jul 10 '17 at 03:35
  • I don't see any code issues just by looking at it. :) Make the variable explicitly available to all is a decision of OP. – CodeMonkey Jul 10 '17 at 03:42
  • My point is that changing `var numberOfMessages = 0` to `window.numberOfMessages = 0` will not change the behaviour of the code. Both create a global (for the code shown). So this doesn't answer the question. – nnnnnn Jul 10 '17 at 03:49
  • This is totally unrelated to the async issue the OP is having. – Soviut Jul 10 '17 at 04:16
  • Sheesh.. I feel very motivated to help more people now. -_- – CodeMonkey Jul 10 '17 at 04:18