Reputation: 1890
I have two classes:
In my application, I have multiple socket connections that I may open - Hence why I don't want to repeat all the logic for opening and closing my socket connection.
Similarly, when I receive a message on one of the connections I may handle the messages differently, depending on what connection I have opened.
Therefore, I came up with the following solution:
class SocketBase {
constructor(messageHandler, errorHandler) {
this.messageHandler = messageHandler
this.errorHandler = errorHandler
}
openSocket = async () => {
//Logic for opening up socket
//Subscribe to socket events
.subscribe(
(x) => this.messageHandler(x),
(err) => this.errorHandler(err),
() => console.log("Observer got a complete notification"),
)
}
}
As you can see, I want to pass two callback functions to my above super-class - Respectively one for handling incoming messages, and another for handling eventual error events.
My sub-class looks as follows:
class Sub extends SocketBase {
constructor(link) {
super(this.messageHandler, this.errorHandler)
}
errorHandler = (err) => {
//some logic
}
messageHandler = (message) => {
//some logic
}
}
Since the incoming messages are events, I thought passing a callback function to the super-class made sense. However, I realize that my sonarlint is complaining.
i.e.
'this' is not allowed before 'super()'.sonarlint(javascript:S3854)
It is however possible for me to define the callback function in my constructor arguments as follows:
super(function(message){console.log(message)}, function(error){console.log(error)})
Ofcause this is not what I want, for obvious reasons the above solution may get very messy.
Another solution would be for me to construct my base-class, but that would give me some undesired issues as well.. For example, I would have to do as follows:
this.socketBase = new SocketBase(this.messageHandler, this.errorHandler)
//Open socket (Not pretty)
openSocket = () => {
this.socketBase.openSocket()
}
Conclusively, I want to understand how I should approach this problem?
Upvotes: 0
Views: 100
Reputation: 56754
With your code example, there is no need to pass the functions, at all:
class SocketBase {
openSocket = async () => {
//Logic for opening up socket
//Subscribe to socket events
.subscribe(
(x) => this.messageHandler(x),
(err) => this.errorHandler(err),
() => console.log("Observer got a complete notification"),
)
}
}
class Sub extends SocketBase {
constructor(link) {
super();
// do whatever you need to do with `link` parameter
}
errorHandler = (err) => {
//some logic
}
messageHandler = (message) => {
//some logic
}
}
If for whatever strange reason you need the passing to the super class, here you go.
You can define constants and pass those to super
, and by calling super, you already assign those to your instance this
.
class Sub extends SocketBase {
constructor(link) {
const errorHandler = (err) => {
// errorHandler Code here
}
const messageHandler = (msg) => {
// messageHandler Code here
}
super(messageHandler, errorHandler)
}
}
You can also work with closures here, but in that case remember to use regular functions and bind them in the superclass:
function errorHandler(err) {
// errorHandler Code here
}
function messageHandler(msg) {
// messageHandler Code here
}
class Sub extends SocketBase {
constructor(link) {
super(messageHandler, errorHandler);
}
}
class SocketBase {
constructor(messageHandler, errorHandler) {
this.messageHandler = messageHandler.bind(this);
this.errorHandler = errorHandler.bind(this);
}
}
Upvotes: 1