1

I want to implement very simple abstract factory pattern but I am facing this error. Also am I doing something wrong with my code? How can I improve this to make it work properly?

Must call super constructor in derived class before accessing 'this' or returning from derived constructor"

Dave
  • 1
  • 1
  • 9
  • 38
  • Drop the `MakePizza` class and create two classes implementing its interface (i.e. having a `createPizza` method). Keep it abstract! – Bergi Jul 11 '22 at 22:29
  • Neither your `Pizza` nor your `MakePizza` class are properly [abstract](https://stackoverflow.com/q/29480569/1048572) – Bergi Jul 11 '22 at 22:37
  • A "simple abstract factory" with only a single method doesn't need to be an abstract factory at all. You could use the simple normal factory pattern. – Bergi Jul 11 '22 at 22:38

1 Answers1

0

You need to call super() inside constructor:

class MakeMeatPizza extends MakePizza {
    constructor() {
        super();
        super.createPizza("meat");
    }
}

So thanks to this beautiful answer:

The rules for ES2015 (ES6) classes basically come down to:

  • In a child class constructor, this cannot be used until super is called.
  • ES6 class constructors MUST call super if they are subclasses, or they must explicitly return some object to take the place of the one that was not initialized.

And the code looks like this:

class Pizza {
    constructor(name,size,type) {
        this.name = name;
        this.size = size;
        this.type = type;
    }

    prepare() {
        console.log("prepare");
    }
    bake() {
        console.log("bake");
    }
    deliver() {
        console.log("deliver");
    }
}

class MeatPizza extends Pizza {
    constructor() {
        super("Chicago style pizza", "Large", "Meat")
    }
}

class VegePizza extends Pizza {
    constructor() {
        super("Only natural", "Large", "Vegetarian")
    }
}

class MakePizza {
    createPizza(type) {
        switch (type) {
            case "meat":
                return new MeatPizza()
            case "vege":
                return new VegePizza()
            default:
                throw new Error("Something went wrong...");
        }
    }
}

class MakeMeatPizza extends MakePizza {
    constructor() {
        super()
    }

    create() {
        return this.createPizza("meat")
    }
}

class MakeVegePizza extends MakePizza {
    constructor() {
        super()
    }

    create() {
        return this.createPizza("vege")
    }
}

class OrderPizza {

}

const test = new MakeVegePizza().create();
console.log(test)
StepUp
  • 36,391
  • 15
  • 88
  • 148
  • but why am I getting an empty object back when I do `const test = new MakeVegePizza()`. I have to make it like this `const test = new MakeVegePizza().createPizza('vege');` to get pizza details – Dave Jul 12 '22 at 06:36
  • @squnk please, see my updated answer. Constructor should return nothing as goal of constructor is to construct object. I've edited code – StepUp Jul 12 '22 at 08:06