{"id":62,"date":"2016-07-01T00:06:00","date_gmt":"2016-07-01T00:06:00","guid":{"rendered":"http:\/\/markcarlson.io\/?p=62"},"modified":"2016-11-18T18:47:36","modified_gmt":"2016-11-18T18:47:36","slug":"javascript-localstorage-sessionstorage-gotchas","status":"publish","type":"post","link":"https:\/\/mc.dev\/javascript-localstorage-sessionstorage-gotchas\/","title":{"rendered":"Javascript localStorage &#038; sessionStorage gotchas"},"content":{"rendered":"<figure id=\"attachment_63\" aria-describedby=\"caption-attachment-63\" style=\"width: 577px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-63 size-large\" title=\"Mobile site image\" src=\"http:\/\/markcarlson.io\/wp-content\/uploads\/2016\/06\/IMG_3694-577x1024.jpg\" alt=\"IMG_3694\" width=\"577\" height=\"1024\" srcset=\"https:\/\/mc.dev\/wp-content\/uploads\/2016\/06\/IMG_3694-577x1024.jpg 577w, https:\/\/mc.dev\/wp-content\/uploads\/2016\/06\/IMG_3694-169x300.jpg 169w, https:\/\/mc.dev\/wp-content\/uploads\/2016\/06\/IMG_3694.jpg 640w\" sizes=\"auto, (max-width: 577px) 100vw, 577px\" \/><figcaption id=\"caption-attachment-63\" class=\"wp-caption-text\">The tabs open but the links don&#8217;t work?!<\/figcaption><\/figure>\n<p>So you write some code, validate the feature, send it off to QA, and move on to something else. \u00a0The last thing you expect is to have a QA engineer come back and say that your code doesn&#8217;t work. \u00a0When that happens, you begin the process of identifying the differences (or the singular difference) between the tester&#8217;s system and yours.<\/p>\n<p>I opened the site on my phone, it works. \u00a0I open the site on his phone, it doesn&#8217;t work.<\/p>\n<p>We both have iPhones. \u00a0Both have the same iOS version. \u00a0Both have the same browser. \u00a0My links work, his don&#8217;t. \u00a0Go figure. \u00a0Wait, why is his border black and mine is white? \u00a0Ahh, he&#8217;s in private browsing mode. \u00a0Well that shouldn&#8217;t make any difference, should it? \u00a0Links are links, right?<\/p>\n<p>So I open an incognito tab, go to the site, and sure enough my links don&#8217;t work either. \u00a0Who would&#8217;ve guessed?<\/p>\n<p>So, I hook up my phone to my computer to open my dev tools and start scouring the console log for errors. \u00a0This one looks unusual:<\/p>\n<pre style=\"padding-left: 30px;\">QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota.<\/pre>\n<p>Turns out I had added a script to save the open tabs to sessionStorage, so subsequent page views would display the open tabs for the user when they opened the hamburger menu. \u00a0Safari&#8217;s mobile browser not only disables localStorage and sessionStorage in private mode, but also throws a fatal error! \u00a0The script stops running. \u00a0In this case, the links did not respond to tap events.<\/p>\n<p>The problem here was pretty easy to fix. \u00a0Test for sessionStorage and use a try\/catch to silently ignore the error:<\/p>\n<pre style=\"padding-left: 30px;\"> if (typeof sessionStorage === 'object') {\r\n   try {\r\n     sessionStorage.setItem('openMobileMenuTabs', JSON.stringify(openMobileTabs));\r\n   } catch (e) {\r\n     \/\/ silently ignore javascript error when sessionStorage is unavailable. The most likely case is Private browsing mode.\r\n   }\r\n }<\/pre>\n<p>Lesson learned. \u00a0Always test your code in private mode on a mobile device when using localStorage or sessionStorage<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So you write some code, validate the feature, send it off to QA, and move on to something else. \u00a0The last thing you expect is to have a QA engineer come back and say that your code doesn&#8217;t work. \u00a0When that happens, you begin the process of identifying the differences (or the singular difference) between [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4],"tags":[7,5,6],"class_list":["post-62","post","type-post","status-publish","format-standard","category-ui","tag-javascript","tag-localstorage","tag-sessionstorage","czr-hentry"],"_links":{"self":[{"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/posts\/62","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/comments?post=62"}],"version-history":[{"count":3,"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/posts\/62\/revisions"}],"predecessor-version":[{"id":107,"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/posts\/62\/revisions\/107"}],"wp:attachment":[{"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/media?parent=62"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/categories?post=62"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mc.dev\/wp-json\/wp\/v2\/tags?post=62"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}