Search code examples
javascriptecmascript-6ternary

why is this ternary throwing an error instead of evaluating to false?


I am trying to test the truthiness of an object property. Whether it exists and has a value use that value and if it does not then add a default value to another object.

const initNetwork = ( setupObj ) => {
    let obj = {};

    obj = Object.assign({}, setupObj);

    obj.eth0 = obj.eth0 ? obj.eth0 : {};
    obj.wlan0 = obj.wlan0 ? obj.wlan0 : {};

    obj.eth0.server = obj.eth0.server ? obj.eth0.server : {};
    obj.wlan0.client = obj.wlan0.client ? obj.wlan0.client : {};
    obj.wlan0.server = obj.wlan0.server? obj.wlan0.server : {};

    obj.eth0.mac = null;
    obj.wlan0.mac = null;

    obj.eth0.server.address = setupObj.eth0.server.address ? setupObj.eth0.server.address : "10.0.0.1";

}

initNetwork(); // intentionally leaving this empty to test setting default values.

I am getting an error here though. I thought it would return undefined and so would set obj.eth0.server.address to the false value of "10.0.0.1".

    obj.eth0.server.address = setupObj.eth0.server.address ? setupObj.eth0.server.address : "10.0.0.1";
                                       ^

TypeError: Cannot read property 'eth0' of undefined

What is the best way to see if this key/value pair exists all the way up the tree and if so use that value, otherwise set the false value?


Solution

  • You are assigning to a new object named obj so your check should be against obj.
    In this situation setupObj will always be undefined.
    You can add another condition for setupObj using the && operator:

    obj.eth0.server.address = (setupObj && setupObj.eth0.server.address) ? setupObj.eth0.server.address : "10.0.0.1";
    

    Of course it is advised to check for each level of nested objects.

    Running example:

    const initNetwork = ( setupObj ) => {
        let obj = {};
    
        obj = Object.assign({}, setupObj);
    
        obj.eth0 = obj.eth0 ? obj.eth0 : {};
        obj.wlan0 = obj.wlan0 ? obj.wlan0 : {};
    
        obj.eth0.server = obj.eth0.server ? obj.eth0.server : {};
        obj.wlan0.client = obj.wlan0.client ? obj.wlan0.client : {};
        obj.wlan0.server = obj.wlan0.server? obj.wlan0.server : {};
    
        obj.eth0.mac = null;
        obj.wlan0.mac = null;
    
        obj.eth0.server.address = (setupObj && setupObj.eth0.server.address) ? setupObj.eth0.server.address : "10.0.0.1";
    
    }
    
    initNetwork(); // intentionally leaving this empty to test setting default values.