I want to be able to receive mqtt messages and display them on a web app. I'm working with AWS Amplify's PubSub and the function calls happen outside of the class component. I can't directly access any of the instance functions/properties from the function outside of it but I need some way to trigger a setState change so that the web app can be re-rendered, right?
I've tried just directly calling the function from the React class, but there's still no re-rendering happening. I've tried making an outside variable, storing the message received in it and then accessing the variable from the React class but still no trigger. Then I researched and found that I could force a re-render every couple of seconds but read that doing such a thing should be avoided. I should be using ComponentDidMount and setState functions but not really understanding how to get this to work.
Again all I'm really trying to do is get the message and update the web app to display the new message. Sounds pretty simple but I'm stuck.
import...
var itemsArr = [];
function subscribe() {
// SETUP STUFF
Amplify.configure({
...
});
Amplify.addPluggable(new AWSIoTProvider({
...
}));
// ACTUAL SUBSCRIBE FUNCTION
Amplify.PubSub.subscribe('item/list').subscribe({
next: data => {
// LOG DATA
console.log('Message received', data);
// GET NAMES OF ITEMS
var lineItems = data.value.payload.lineItems;
lineItems.forEach(item => itemsArr.push(item.name));
console.log('Items Ordered', itemsArr);
// THIS FUNCTION CALL TRIGGERS AN ERROR
// CANT ACCESS THIS INSTANCE FUNCTION
this.update(itemsArr);
},
error: error => console.error(error),
close: () => console.log('Done'),
});
}
// REACT COMPONENT
class App extends Component {
constructor(props){
super(props);
this.state = {
items:null,
};
}
// THOUGHT I COULD USE THIS TO UPDATE STATE
// TO TRIGGER A RE-RENDER
update(stuff){
this.setState({items: stuff});
}
render() {
// THINK SUBSCRIBE METHOD CALL SHOULDN'T BE HERE
// ON RE-RENDER, KEEPS SUBSCRIBING AND GETTING
// SAME MESSAGE REPEATEDLY
subscribe();
console.log('items down here', itemsArr);
return (
<div className="App">
<h1>Test</h1>
<p>Check the console..</p>
<p>{itemsArr}</p>
</div>
);
}
}
export default App;
Ideally, I'd like columns of the list of items to be displayed as messages come in but I'm currently getting an error - "TypeError: Cannot read property 'update' of undefined" because the subscribe function outside of the class doesn't have access to the update function inside the class.