Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Responding in onMessage does not work #150

Open
andigehle opened this issue Mar 1, 2014 · 14 comments
Open

Bug: Responding in onMessage does not work #150

andigehle opened this issue Mar 1, 2014 · 14 comments

Comments

@andigehle
Copy link

I'am trying to develop a chrome extension with dart.
To explain my problem let's take a look at this simple extention:

In the background-script i'm calling:

import 'package:chrome/chrome_ext.dart' as chrome;


void main() {
  //...
  //Binde event-listeners
  chrome.runtime.onMessage.listen(onMessage);
  //...
}

/**
 * Message event handling
 */
bool onMessage(chrome.OnMessageEvent messageEvent){

  JsObject message = messageEvent.message;
  JsFunction response = messageEvent.sendResponse;

  switch(message['action']){

    //...

    //Used by popup
    case 'refresh':
      print('Refresh called!');
      chrome.storage.sync.get().then((_){
        new JsObject(response, [new JsObject.jsify({'done': true})]);
      });

      //Idicate to send a response asynchronously (So it's said in the OnMessageEvent Api-Ref.)
      return true;

    //...
  }

  return false;
}

My popup-scripts looks like this:

//...
chrome.runtime.sendMessage({
  'action': "refresh"
}).then((_){
  print('receiving response!');
});
//...

What is working: The message 'refresh' send from popup-script to background-script works! The background-script prints Refresh called!.

What is not working: The popup-script never receives the response called from the background-script: new JsObject(response, [new JsObject.jsify({'done': true})]);.

I don't know how to handel sendResponse to really send an response. Maybe my call with JsObject is wrong? Hope someone else can help. (Btw. also a non async-response doesn't work here.)

@adam-singer
Copy link
Member

does calling response(new JsObject.jsify({'done': true})); work?

@zoechi
Copy link

zoechi commented Mar 1, 2014

the question on SO http://stackoverflow.com/questions/22114022/

@andigehle
Copy link
Author

@financecoding With response(new JsObject.jsify({'done': true})); i have a compiler-error:
response is no method
and a runtime-error:
Exception: Class 'JsFunction' has no instance method 'call'. NoSuchMethodError : method not found: 'call' Receiver: Instance of 'JsFunction' Arguments: [Instance of 'JsObject']

@zoechi
Copy link

zoechi commented Mar 2, 2014

I tried response.apply([new JsObject.jsify({'done': true})]);
This doesn't lead to an exception but the provided JavaScript callback doesn't get called either.

@zoechi
Copy link

zoechi commented Mar 2, 2014

Using @draškoKokić s solution I was able to send messages in both directions (he uses dart:js instead of chrome.dart)

@andigehle
Copy link
Author

Yep. I can work with his solution to use the js-version of the chrome-api. Thanks for the help.
But of course i would prefer the dart-version. :)

So this is a bug in chrome.dart?

@zoechi
Copy link

zoechi commented Mar 2, 2014

I see it as temporary workaround. I would also prefer using chrome.dart.

@andigehle
Copy link
Author

Played a bit around what exactly is not working in chrome.dart - Seems that the bug should be in the eventlistener-part.

Using context['chrome']['runtime']['onMessage'].callMethod('addListener', [onMessageListener]); in the background-script as DraškoKokić discribed, but sending and receiving the response with:

//...
chrome.runtime.sendMessage({
  'action': "refresh"
}).then((_){
  print('receiving response!');
});
//...

also works.

@zoechi
Copy link

zoechi commented Mar 2, 2014

I came to the same conclusion.
On Mar 2, 2014 6:26 PM, "Andreas Gehle" [email protected] wrote:

Played a bit around what exactly is not working in chrome.dart - Seems
that the bug should be in the eventlistener-part.

Using context['chrome']['runtime']['onMessage'].callMethod('addListener',
[onMessageListener]); in the background-script as DraškoKokić discribedhttp://stackoverflow.com/a/22128632/3340378,
but sending and receiving the response with:

//...chrome.runtime.sendMessage({
'action': "refresh"}).then((_){
print('receiving response!');});//...

also works.


Reply to this email directly or view it on GitHubhttps://github.com//issues/150#issuecomment-36459933
.

@adam-singer
Copy link
Member

any suggestions on what type of code we need to generate so this can be done purely with chrome.dart? Does the SO answer actually full fill the the solution?

@zoechi
Copy link

zoechi commented Mar 3, 2014

I think some code like this is missing https://github.com/dart-gde/chrome.dart/pull/52/files#diff-eec526293951e120cef02fa5674414aaR336
I couldn't find code in chrome.dart that forwards chrome.runtime.onMessage.listen(onMessage); to context['chrome']['runtime']['onMessage'].callMethod('addListener', [onMessageListener]);

#135 is probably a similar problem (port.onMessage.addListener().then(processMessage);).
#134 might be the similar too. I couldn't find code where this is forwared to JS.

@andigehle andigehle changed the title Bug or missunderstanding: How to send a response in onMessage? Bug: Responding in onMessage does not work Sep 3, 2014
@gyulavoros
Copy link

Does anyone have any update on the native chrome.dart progress?

@dsemi
Copy link

dsemi commented May 15, 2017

Just ran into this issue myself. I have some native JS code in an extension pop up that sends a message to the background script that's written in Dart.

// popup.js
chrome.runtime.sendMessage({command: 'newSession'}, (sessionId) => {
  console.log(sessionId);
});

// background.dart
...
bool messageListener(chrome.OnMessageEvent onMessageEvent) {
  onMessageEvent.sendResponse.apply(['testString']);
}
chrome.runtime.onMessage.listen(messageListener);
...

I found that the sendResponse function was being called but sessionId is undefined. Tried with JS objects (via JsObject.jsify(...)) as well with the same result; the data in the callback attached to sendMessage doesn't appear to be populating properly.

@dsemi
Copy link

dsemi commented May 15, 2017

If I change ChromeRuntime in lib/gen/runtime.dart to pass true as the fourth param (returnVal) to the ChromeStreamController i.e.

_onMessage = new ChromeStreamController<OnMessageEvent>.threeArgs(getApi, 'onMessage', createOnMessageEvent, true);

then the messages appear to send properly.

Not sure that should be the default behavior though since that will always leave the message channel open until sendResponse is called.

The issue seems very similar to #252

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants