206

Why this does not work ?

if(typeof(localStorage.getItem("username"))=='undefined'){
    alert('no');
};

The goal is to redirect the user from the index page to the login page if not already logged. Here the localStorage.getItem("username")) variable is not defined for the moment.

It's for an ios phonegap app.

UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
Gabriel
  • 2,331
  • 2
  • 13
  • 18
  • 2
    I'm surprised no one said it yet - client side security is highly discouraged. One can simply hit F12 and run `localStorage['username']='admin'` then mess with your website. – oriadam Apr 07 '16 at 14:07
  • 5
    @oriadam I hope that no one is basing the authorization on the localStorage, but it is perfectly fine storing the JWT accessToken in the localStorage. – Filippo De Luca Oct 28 '17 at 17:03

4 Answers4

421

Quoting from the specification:

The getItem(key) method must return the current value associated with the given key. If the given key does not exist in the list associated with the object then this method must return null.

You should actually check against null.

if (localStorage.getItem("username") === null) {
  //...
}
UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
  • 3
    Thanks, it was my first mistake ! But it doesnt' work too with if(typeof(localStorage.getItem("username"))===null){ alert('no') }; – Gabriel Apr 15 '13 at 08:42
  • 21
    Typeof of `null` is `"null"`, not `null` (hope I'm making sense). – georg Apr 15 '13 at 08:45
  • 4
    @Gabriel: Remove `typeof(..)`. Check my answer again. – UltraInstinct Apr 15 '13 at 08:47
  • 1
    It's worth noting that the constraints FF (28.0) imposes on its localStorage table allows null values: `CREATE TABLE webappsstore2 (scope TEXT, key TEXT, value TEXT, secure INTEGER, owner TEXT)` while Chrome does not: `CREATE TABLE ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)` – Hans Apr 05 '14 at 02:22
  • 1
    @Derin Nope, what if "username" actually exists, but the stored value is false ? – UltraInstinct Aug 22 '14 at 06:03
  • @Derin That condition is not a check for existence (as per the question), rather its a check for truth value. In other words, the question asks how to check if the key is present or not; it does not ask how to check if the value against the key is truth-y or false-y. There is a big difference between the two. You are suggesting a mix of both. I hope you understand. For any discussion beyond this, may be we can use a chat room. – UltraInstinct Aug 25 '14 at 06:44
  • What if null is stored in this key? This kind of check will fail. – Vyshnia Aug 12 '22 at 10:07
76

This method worked for me:

if ("username" in localStorage) {
    alert('yes');
} else {
    alert('no');
}
zb226
  • 9,586
  • 6
  • 49
  • 79
user3332298
  • 801
  • 6
  • 2
  • 1
    this is the best option, in my opinion, as it distinguishes between whether a value has been set and whether it may be false/falsey. – Allan Nienhuis Mar 29 '18 at 16:12
  • 13
    This solution gives false positives for keys like `length`. The accepted answer is the correct way to solve this problem. – kamoroso94 Aug 10 '18 at 14:32
  • I like this solution. It's clean. – Stuart Feb 16 '22 at 12:05
  • The accepted solution didn't work. Although yours, was completely a life saver! Thank you :-) – manjiro sano Jul 06 '22 at 13:06
  • This method will work most of the time, but will catch you out one day. Run `localStorage.__proto__` in the development console and you will see the properties that will conflict. – rob Mar 15 '23 at 11:41
37

Update:

if (localStorage.hasOwnProperty("username")) {
    //
}

Another way, relevant when value is not expected to be empty string, null or any other falsy value:

if (localStorage["username"]) {
    //
}
oriadam
  • 7,747
  • 2
  • 50
  • 48
Derin
  • 1,202
  • 1
  • 15
  • 25
  • 2
    It's short for `if( localStorage["username"]==undefined )` – Allan Ruin Mar 29 '15 at 02:58
  • 11
    Not quite - it's a short for `if (localStorage["username"]==undefined || localStorage["username"]==0 || localStorage["username"]==null || localStorage["username"]==false || localStorage["username"]=='')` @AllanRuin – oriadam Apr 07 '16 at 14:01
  • 5
    @oriadam Not quite; you both got it backwards. It's short for `if (localStorage["username"]!==undefined && localStorage["username"]!==0 && localStorage["username"]!==null && localStorage["username"]!==false && localStorage["username"]!=='')` – JoL Jul 21 '18 at 16:22
  • 1
    @JoL lol you're right :) I'm updating the answer – oriadam Jul 21 '18 at 17:17
  • 1
    This method seems better because it just checks for the key without needlessly returning the key value, e.g., if (localStorage.getItem(key) === null) – Yogi Dec 15 '21 at 14:09
  • But if "username" is set as any of the falsy values, then (localStorage["username"]) { // } will pass as truthy because the localStorage stores these values as "string". you will be getting "undefined","null"..etc – kob003 May 12 '23 at 07:34
20

The MDN documentation shows how the getItem method is implementated:

Object.defineProperty(oStorage, "getItem", {
      value: function (sKey) { return sKey ? this[sKey] : null; },
      writable: false,
      configurable: false,
      enumerable: false
    });

If the value isn't set, it returns null. You are testing to see if it is undefined. Check to see if it is null instead.

if(localStorage.getItem("username") === null){
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    Right, I answered to Thrustmaster above. But it doesn't work better with this :/ – Gabriel Apr 15 '13 at 08:44
  • 1
    It [works for me](http://jsbin.com/osujaf/1/edit). – Quentin Apr 15 '13 at 08:47
  • 1
    @Gabriel — In your comment above you are comparing the `typeof` the value to null. You need to compare the actual value. – Quentin Apr 15 '13 at 08:48
  • 1
    Or use `==` instead of `===` because (for some weird reason) `null==undefined` is true. Then again, you don't need anything, like @Derin answered, you can simply `if (localStorage["username"])` – oriadam Apr 07 '16 at 14:04