Search code examples
javascriptdevicedetectionuser-agent

JavaScript Device Detection Almost Finished but 1 error in Google Chrome's error console


I'm writing a Device & Feature detection library (not really for any real use, just experimenting and playing around), and as far as the device detection, I should be done, but I have just one (I think) issue. My code:

var $device = {

    mobile: {
        android: navigator.userAgent.match(/Android/i),
        blackberry: navigator.userAgent.match(/BlackBerry/i),
        iphone: navigator.userAgent.match(/iPhone/i),
        ipod: navigator.userAgent.match(/iPod/i),
        opera: navigator.userAgent.match(/Opera Mini/i),
        windows: navigator.userAgent.match(/(Windows Phone OS|Windows CE|Windows Mobile|IEMobile)/i)
    },

    tablet: {
        ipad: navigator.userAgent.match(/iPad/i),
        galaxy_tab: navigator.userAgent.match(/(GT-P1000|GT-P1000R|GT-P1000M|SGH-T849|SHW-M180S)/i),
        windows: navigator.userAgent.match(/Tablet PC/i)
    },

    desktop: {
        other: navigator.userAgent.match(/(Linux|X11)/i),
        mac: navigator.userAgent.match(/(Macintosh|Mac OS X)/i),
        windows: navigator.userAgent.match(/Windows/i)
    }

}

$device = {
    mobile: {
        any: $device.mobile.android || $device.mobile.blackberry || $device.mobile.iphone || $device.mobile.ipod || $device.mobile.opera || $device.mobile.windows
    },

    tablet: {
        any: $device.tablet.ipad || $device.tablet.galaxy_tab || $device.tablet.windows
    },

    desktop: {
        any: $device.desktop.other || $device.desktop.mac || $device.desktop.windows
    }
}

if($device.mobile.any) {
    $device = {
        type: "Mobile Phone"
    }
} else if($device.tablet.any) {
    $device = {
        type: "Tablet"
    }
} else if($device.desktop.any) {
    $device = {
        type: "Desktop"
    }
}

if($device.desktop.windows){alert("Hello")}

Now, as far as the userAgent strings go, I'm not fully convinced that they are all correct and I have not tested them yet, however this is not my problem. My problem is, that it won't alert "hello", and the error message in google chrome's developer tools is: Uncaught TypeError: Cannot read property "windows" of undefined

Now, with my experience with Google's tool, this is telling me that somewhere my syntax is incorrect, and not my method, but I can't seem to get it. Any help? (By the way: I know user agent sniffing is no good, that's why I'll later back it with feature detection also.)


Solution

  • You are reassigning $device often, blowing away what it previously had. By the time the script gets to the bottom, $device.desktop.windows no longer exists, because at that point $device is simply going to have type and no other properties.

    Instead of reassigning device each time, add to it:

    var $device = {
        mobile: {
            ...
        }
    };
    
    ...
    
    $device.mobile.any = $device.mobile.android || $device.mobile.blackberry || ... ;