Amplify-js: PubSub: How do I know data from which topic

Created on 14 Jun 2018  路  9Comments  路  Source: aws-amplify/amplify-js

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

PubSub.subscribe(['myTopic1','myTopic2']).subscribe(myHandler);
In callback I can get value and provider object.
But how do i know data from which topic ?

PubSub feature-request

Most helpful comment

I was having a similar problem and I found a way to get the topic from the data.

const topic = data.value[Object.getOwnPropertySymbols(data.value)[0]]

I did not know what Symbols were until I came across this article

Let me know if this works for you!

All 9 comments

Is there even an undocumented way to get this? I see _topicObservers available when the data is received, but no clear way to figure out which topic this message came from.

Would (a non-ideal) alternative be to create different subscriptions?

const subA = PubSub.subscribe('topicA').subscribe(() => {next: handlerA})
const subB = PubSub.subscribe('topicB').subscribe(() => {next: handlerB})

I was having a similar problem and I found a way to get the topic from the data.

const topic = data.value[Object.getOwnPropertySymbols(data.value)[0]]

I did not know what Symbols were until I came across this article

Let me know if this works for you!

@jangwonsuh Thanks for the suggestion. It's not working for me, although I am still using 0.3.4 of Amplify and that might be the issue. The article on Symbols was interesting. Thanks for the share. I will work on updating my lib to a post 1.x release and try your suggestion again.

@jangwonsuh Thanks! It works.

I updated to the latest and finally took some time to dig into the code. Unrelated, I submitted a PR to address an exception dealing with parsing messages, but it turns out the topic Symbol only works if the parsed message is an object.

The relevant bit is in MqttOverWSProvider.ts:

if (typeof parsedMessage === 'object') {
  parsedMessage[topicSymbol] = topic;
}

One potential suggestion (looking for feedback before submitting a PR), would be to update the observable.next with the topic embedded like so:
```
if (typeof parsedMessage === 'object') {
parsedMessage[topicSymbol] = topic;
}

matchedTopicObservers.forEach(observersForTopic =>{
const value = {
value: parsedMessage, // 'value' key should retain backward compatability
topic: topic
}
observersForTopic.forEach(observer => observer.next(value));
});

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Please don't close, this really should be added. Otherwise using filters for topics has limited utility.

data.provider.getTopicForValue(data.value)
https://github.com/aws-amplify/amplify-js/blob/main/packages/pubsub/src/Providers/MqttOverWSProvider.ts#L93-L95

But, I want to get topic simply and generally...

When the data is provider-specific, I recommend subscribing individually PubSub.subscribe(topic) rather than with [...topics]:

https://docs.amplify.aws/lib/pubsub/subunsub/q/platform/js#subscribe-to-a-topic

Subscribing to multiple topics at once works best when multiple topics are publishing the same data types.

It slightly changes the implementation (one PubSub.subscribe vs. multiple PubSub.subscribes), but allows for easier TypeScript support as well (whereas supporting multiple topics would require union types & logic gates in your code).

Was this page helpful?
0 / 5 - 0 ratings