Search code examples
javascriptfactory-pattern

Javascript factory pattern with a default, not working


In school I had to make a Javascript script using Javascript's Factory Pattern Design, that "made" pizzas. The Factory function had to receive 3 arguments (an array of strings for the ingredients, the price of the pizza, and a string for the price), and if an argument was missing it had to return a default Pepperoni Pizza.

I used this code:

function pizzaFactory(ing, pric, siz) {
    let ingred = null;
    let price = null;
    let size = null;
    if(typeof ing == "undefined" || typeof pric == "undefined" || typeof siz == "undefined") {
        ingred = ["pepperoni", "cheese", "tomato sauce", "lots and lots and lots and lots and lots of love"];
        price = 125;
        size = "Small";
    } else {
        ingred = ing;
        price = pric;
        size = siz;
    }
    return {
        ing: ingred,
        pric: price,
        siz: size,
        deliver: function() {
            console.log(`Pizza Ingredients: ${ing}`);
            console.log(`Price: ${pric}`);
            console.log(`Size: ${siz}`);
        }
    };
}
let ingredients = ['cheese', 'tomato sauce', 'hate'];
const pizza1 = pizzaFactory(ingredients, 150, "Large");
pizza1.deliver();
const pizza2 = pizzaFactory();
pizza2.deliver();

The problem is that the function only works when passing all arguments, and although the function enters the if and assigns correctly the value to the variables ingred, price and size. When running the deliver function the values appear as undefined.

I was wondering what's the problem with my code, and if there's a better/more effective way for doing it.

Thanks.


Solution

  • Inside the function, the input arguments are named ing, pric, and siz. Then, the validated values are put into the variables ingred, price, and size.

    Currently, in the returned object, you're referencing ing, pric, and siz, rather than the validated variables - fix that, and it works as intended:

    function pizzaFactory(ing, pric, siz) {
        let ingred = null;
        let price = null;
        let size = null;
        if(typeof ing == "undefined" || typeof pric == "undefined" || typeof siz == "undefined") {
            ingred = ["pepperoni", "cheese", "tomato sauce", "lots and lots and lots and lots and lots of love"];
            price = 125;
            size = "Small";
        } else {
            ingred = ing;
            price = pric;
            size = siz;
        }
        return {
            ing: ingred,
            pric: price,
            siz: size,
            deliver: function() {
                console.log(`Pizza Ingredients: ${ingred}`);
                console.log(`Price: ${price}`);
                console.log(`Size: ${size}`);
            }
        };
    }
    let ingredients = ['cheese', 'tomato sauce', 'hate'];
    const pizza1 = pizzaFactory(ingredients, 150, "Large");
    pizza1.deliver();
    const pizza2 = pizzaFactory();
    pizza2.deliver();

    This is one reason why precise variable names are important. You might consider using different ones, to make the difference clear: for example, maybe ingredArg and ingredValidated:

    function pizzaFactory(ingArg, pricArg, sizArg) {
        const argsValid = [ingArg, pricArg, sizArg].every(arg => arg !== undefined)
        const ingredValidated = argsValid ? ingArg : ["pepperoni", "cheese", "tomato sauce", "lots and lots and lots and lots and lots of love"];
        const priceValidated = argsValid ? pricArg : 125; 
        const sizeValidated = argsValid ? sizArg : 'Small';
        return {
            ing: ingredValidated,
            pric: priceValidated,
            siz: sizeValidated,
            deliver: function() {
                console.log(`Pizza Ingredients: ${ingredValidated}`);
                console.log(`Price: ${priceValidated}`);
                console.log(`Size: ${sizeValidated}`);
            }
        };
    }
    let ingredients = ['cheese', 'tomato sauce', 'hate'];
    const pizza1 = pizzaFactory(ingredients, 150, "Large");
    pizza1.deliver();
    const pizza2 = pizzaFactory();
    pizza2.deliver();