-1

I am using Google Cloud Channels in Android's WebView, but the same problem probably occurs as well when using any socket in a similar way.

Problem: The argument is not passed on by the handler, possibly because functions are called in a different scope.

Here is my code:

<html>
    <head>
        <script src='{{ channelurl }}jsapi'></script>
    </head>
    <body>
        <script type="text/javascript">

            onMessage = function(message) {

            };

            var token = '{{ token }}';
            var channel = new goog.appengine.Channel(token);

            var handler = {
                'onmessage': onMessage,
            };

            var socket = channel.open(handler);

            socket.onmessage = onMessage;

        </script>
    </body>
</html>

onMessage has a single argument (string) and my onMessage function is properly called, but the argument is 'undefined', probably because it is in a different scope.

This question might be a duplicate of these or other similar questions, and I tried to apply the recipes given there, but no success.

How do I pass arguments to an event handler? How to pass event as argument to an inline event handler in JavaScript?

I actually applied the code from here

http://2cor214.blogspot.com/2010/08/passing-arguments-to-event-handler-in.html

and tried to play with things like this:

socket.onmessage = (function (message) {return onMessage})(message)

in many variants, but couldn't get it to work.

I admit I am not normally developing JavaScript and I don't exactly understand what JavaScript does here, but it seems to me that the argument needs to be extracted the function wrapped somehow.

Can anybody shed light please.

--

I removed parts of my code for brevity.

Community
  • 1
  • 1
Oliver Hausler
  • 4,501
  • 4
  • 30
  • 62

1 Answers1

0

The problem was not a JavaScript issue, as I assumed. The assumption that the same issue would occur with any socket type was also incorrect.

The problem had to do with how Google Cloud Channels hands over the message in onMessage().

As I could see from code that Google posted for their Tic Tac Toe example here http://code.google.com/p/channel-tac-toe/source/browse/trunk/index.html, line 175ff, they hand over the string as an event with the variable "data", but called the argument "m" (as in message).

  onOpened = function() {
     sendMessage('/opened');
  };

  onMessage = function(m) {
     newState = JSON.parse(m.data);
     state.board = newState.board || state.board;
     state.userX = newState.userX || state.userX;
     state.userO = newState.userO || state.userO;
     state.moveX = newState.moveX;
     state.winner = newState.winner || "";
     state.winningBoard = newState.winningBoard || "";
     updateGame();
  }

  openChannel = function() {
     var token = '{{ token }}';
     var channel = new goog.appengine.Channel(token);
     var handler = {
       'onopen': onOpened,
       'onmessage': onMessage,
       'onerror': function() {},
       'onclose': function() {}
     };

     var socket = channel.open(handler);
     socket.onopen = onOpened;
     socket.onmessage = onMessage;
   } 

Kind of confusing and undocumented here https://cloud.google.com/appengine/docs/java/channel/?csw=1 and here https://cloud.google.com/appengine/docs/java/channel/javascript, but when I changed the message signature to

        onMessage = function(message) {
            ChannelListener.onMessage(message.data); // message
        };

it worked perfectly fine.

Oliver Hausler
  • 4,501
  • 4
  • 30
  • 62