I have a base class in ES6 like this:
class BasePlot {
props = {
'data': []
}
constructor() {
// do things but don't setup data
}
draw(data){
if (data && data.length )
this.props.data = data;
// Q: how to exit here if height and width are not yet available?
this.setScale()
this.setAxis()
}
setDimensions(height, width) {
this.props.height = height;
this.props.width = width;
}
}
The class will never be instantiated directly but will be used only for inheritance.
Apart the constructor, all the other methods might be called in unpredictable order, that is why in the draw method I don't want to proceed if height and width are not yet defined for the instance.
I could simply add an if condition and exit but that's not what I had in mind.
In a child class I call the parent draw like this:
class RectPlot extends BasePlot{
draw(data){
super.draw(data);
// DON'T EXECUTE if height and width are not set
// rest of the code
}
}
In this case when I call the child draw I first call the parent method, and in case the height and width are not set yet I'd like to exit (return) from the parent method but ALSO from the child one.
What I mean, is something like this:
// Parent
draw(data){
if (data && data.length )
this.props.data = data;
if(this.props.height && this.props.width)
this.setScale()
this.setAxis()
return true
}
else return false
}
}
// Child
draw(data){
if(super.draw(data)){
// proceed w rest of the code
}
else return false
}
This is exactly what I'd like to do, except I don't want to check with an if in all the subclasses if the parent draw completed successfully.
Q: Is there a way to 'early exit' a parent AND a child method besides the aforementioned repetition of the if-else block in all the children classes?
You cannot return from a caller method from within a called method. However, you could avoid the problem altogether...
An alternative design could be to create another method, say drawCanvas for example, as follows...
class BasePlot {
props = {
data: [],
};
draw(data) {
if (data && data.length) this.props.data = data;
if (this.props.height && this.props.width) this.drawCanvas(data);
}
drawCanvas(data) {
this.setScale();
this.setAxis();
}
}
class RectPlot extends BasePlot {
drawCanvas(data) {
super.drawCanvas(data);
// other stuff
}
}
You would then override drawCanvas instead of draw, knowing that drawCanvas is only called if width and height exist.
I agree that checking the returned value of super.draw(data), as in your example, is not ideal. It would be easy to forget this check, leading to potential errors. It is also not obvious to the reader of the child class implementation why this check is required without looking at the base class implementation.