Reputation: 10947
I have a listener setup in my componentDidMount:
updateBasketTotal: function() {
BasketService.getBasketTotal(function(data){
this.setState({
selectedPeopleCount: data.TotalMembers
});
}.bind(this));
},
componentDidMount: function() {
this.updateBasketTotal();
this.subscribeToChannel(basketChannel,"selectAll",this.listenerSelectAll);
this.subscribeToChannel(basketChannel,"removePersonFromBasket",this.listenerRemovePersonFromBasket);
this.subscribeToChannel(basketChannel,"addPersonToBasket",this.listenerAddPersonToBasket);
this.subscribeToChannel(basketChannel,"addArrayToBasket",this.listenerAddArrayToBasket);
},
listenerAddArrayToBasket: function(data){
BasketService.addPerson(data.arrayToPush,function(){
this.updateBasketTotal();
});
},
listenerAddPersonToBasket: function(data){
BasketService.addPerson(data.personId,function(){
this.updateBasketTotal();
});
},
listenerRemovePersonFromBasket: function(data){
BasketService.removePerson(data.personId,function(){
this.updateBasketTotal();
});
},
listenerSelectAll: function(data){
BasketService.selectAll(data.selectAll, function () {
this.updateBasketTotal();
});
}
However, if I publish a message when I'm not on this page, I get an error:
this.updateBasketTotal is not a function
Can anyone please tell me how I can use this.updateBasketTotal?
I think its a problem with 'this' but not sure how to fix it. Thanks in advance
UPDATE:
Have tried adding bind() to the listener:
listenerAddPersonToBasket: function(data){
BasketService.addPerson(data.personId,function(){
this.updateBasketTotal();
}.bind());
},
But no joy, any ideas?
Upvotes: 1
Views: 931
Reputation: 3485
I assume your component is unsubscribing to those channels in componentWillUnmount
to avoid resource leaks and duplicate subscriptions.
The asynchronous callbacks should call isMounted
to ensure the component is still mounted before attempting anything else.
BasketService.selectAll(data.selectAll, function () {
if (this.isMounted()) {
this.updateBasketTotal();
}
}.bind(this));
I don't know if the isMounted check will solve your problem since that may also not be a function anymore. If it isn't, you might consider adding your own property to track whether the component is mounted or not and check that rather calling a function.
Upvotes: 2
Reputation: 2279
listenerAddArrayToBasket: function(data) {
var _this = this;
BasketService.addPerson(data.arrayToPush,function() {
_this.updateBasketTotal();
});
}
or
listenerAddArrayToBasket: function(data) {
BasketService.addPerson(data.arrayToPush,function() {
this.updateBasketTotal();
}.bind(this));
}
React does not bind context by default, you have to do it yourself. In your example this would refer to callback function, not to react object. You can either assign react context to a variable and use it inside your callback, or bind context directly to callback.
Here is the great article explaining contexts in JavaScript
Also in ES6 it's possible to use double arrow declaration
class SomeComponent extends React.Component {
updateBasketTotal() {
....
}
lisneterAddArrayToBasket() {
BasketService.addPerson(data.arrayToPush, () => {
this.updateBasketTotal()
})
}
}
You can use babel to compile your ES6 code to old plain ES5 :)
Upvotes: 0