Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript Local Storage Project

Anwar Rizalman
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Anwar Rizalman
Python Development Techdegree Graduate 33,620 Points

Why doesn't this work on Safari?

I've tried working this on Safari but the submit button does not work, however it works when I run it on Chrome.

The supportLocalStorage if condition is true in Safari, but why doesn't work?

Neil McPartlin
Neil McPartlin
14,662 Points

I normally work with Chrome on a Windows 7 machine, but I have just fired up my Mac which is running Safari 10.1.2 and all seems well. I can add entries both by hitting the 'enter' key and by clicking the 'Search' button. Clicking the 'Clear Storage' button works too.

I am using 'Workspaces' which ensures the environment is identical for both browsers. If you are using 'Workspaces too, please feel free to post a snapshot here and I will check if it works here with me.

Anwar Rizalman
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Anwar Rizalman
Python Development Techdegree Graduate 33,620 Points

This is the code that I used. I just went through the code again and didn't find any code typo error and it still does not work in Safari but works in Chrome.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>Search Bar Demo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="stylesheets/page.css" />
  <link href='https://fonts.googleapis.com/css?family=Bitter:400,700' rel='stylesheet' type='text/css'>
</head>
<body>

  <div class="header">
    <h1 class="header-title">Search</h1>
    <form autocomplete="off" id="searchForm">
      <input class="text-input" type="text" id="searchBar">
      <button class="button" type="submit">Search</button>
    </form>
  </div>

  <div class="recent">
    <h2 class="recent-title">Recent Searches</h2>
    <button class="button" type="button" id="clearStorage">Clear Storage</button>
    <ul class="recent-list" id="recentSearchList"></ul>
  </div>

  <script type="text/javascript">
    'use strict';

    function supportsLocalStorage() {
      try {
        return 'localStorage' in window && window['localStorage'] !== null;
      } catch(e)  {
        return false;
      }
    }

    function getRecentSearches() {
      var searches = localStorage.getItem('recentSearches'); 
      if(searches) {
        return JSON.parse(searches);
      } else {
            return [];
      }
    }

    function saveSearchString(str) {
      var searches = getRecentSearches(); 
      if(!str || searches.indexOf(str) > -1) { 
        return false;
      }
      searches.push(str);
      localStorage.setItem('recentSearches', JSON.stringify(searches));
      return true;
    }


    function removeSearches() {
      localStorage.removeItem('recentSearches');
    }

    // Create an li, given string contents, append to the supplied ul
    function appendListItem(listElement, string) {
      var listItemElement = document.createElement('LI');
      listItemElement.innerHTML = string;
      listElement.appendChild(listItemElement);
    }

    // Empty the contents of an element (ul)
    function clearList(listElement) {
      listElement.innerHTML = '';
    }

    window.onload = function() {

       if (supportsLocalStorage()) {

            var searchForm = document.getElementById('searchForm');
            var searchBar = document.getElementById('searchBar');
            var recentSearchList = document.getElementById('recentSearchList');
            var clearButton = document.getElementById('clearStorage');

            // Initialize display list
            var recentSearches = getRecentSearches();
            recentSearches.forEach(function(searchString) {
              appendListItem(recentSearchList,searchString);
            });

            // Set event handlers
            searchForm.addEventListener('submit', function(event) {
              var searchString = searchBar.value;
              if (saveSearchString(searchString)) { 
                appendListItem(recentSearchList, searchString);
              }
            });

            clearButton.addEventListener('click', function(event) {
              removeSearches();
              clearList(recentSearchList);
            });
     }
    };
  </script>
</body>
</html>
Neil McPartlin
Neil McPartlin
14,662 Points

I replaced my html file with yours and Safari is still working. Some things to think about...

  1. It's always best to provide a full 'snapshot', because there are other files involved that may be causing the problem.
  2. Is your Safari at my version (10.1.2) or even more recent?
  3. Are you using 'Workspaces' or did you download the work files locally? If the latter, try using a workspace so you can be certain that Chrome and Safari are working with the same files.
  4. I have assumed that you are using a Mac running MacOS, but if you are using iOS (iPhone/iPad) please say.
Neil McPartlin
Neil McPartlin
14,662 Points
  1. Ahh, I see the confusion with the name, but 'snapshot' does not mean 'screenshot'. Please scroll up to my first post and click on 'snapshot' to learn how to do one.

  2. Yes, that's your MacOS version (Sierra) and I'm one version behind (El Capitan), but we're both using the same Safari version. In Safari, top menu, click on Safari -> About Safari and you should find it is 10.1.2 like mine.

  3. Noted.

  4. Noted.

  5. While playing with Safari I note it is possible to disable JavaScript, so please check yours is enabled. I did find that with it disabled, the demo search site does behave as you said i.e. nothing happens when you type in entries. That said, I also found that 'workspaces' won't even load, so I think this is less likely to be the issue for you. So, in Safari, top menu, click on Safari -> Preferences -> Security -> Web Content: (Enable JavaScript).

  6. I googled Safari to find how to enable the dev tools. In Safari, top menu, click on Safari -> Preferences -> Advanced and at the bottom tick 'Show Develop menu in menu bar'. Now in the Safari top menu you will see 'Develop', so click it and choose 'Show JavaScript Console'. Now try adding some test entries to the search site and see if you witness any error messages.

Anwar Rizalman
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Anwar Rizalman
Python Development Techdegree Graduate 33,620 Points

So sorry for the confusion on my part.

  1. https://w.trhou.se/r7yand0ks4

  2. I didn't realize you meant Safari ! oops.

  3. Yeap, it is already enabled.

  4. TypeError: recentSearches.forEach is not a function. (In 'recentSearches.forEach(function(searchString) { appendListItem(recentSearchList,searchString); })', 'recentSearches.forEach' is undefined) This is the error that came up in the dev console. I'm not sure how to fix this though. Its saying that the recentSearches is not a function. I checked twice with the video, there's no changes in that particular line.

1 Answer

Neil McPartlin
Neil McPartlin
14,662 Points

I think we're getting warm. I tested your 'snapshot' and it works fine here so your coding is good.

But take a look at this other thread...

https://teamtreehouse.com/community/unexpected-type-error-recentsearchesforeach-is-not-a-function

It could be that your browser's localStorage may already contain a corrupted entry, which is leading to that error message. So in Safari, reload your 'Search' website, then in the Safari top menu click 'Develop', and choose 'Show JavaScript Console'. Here select 'Storage'. On the left choose Local Storage. Select the key 'recentSearches' and delete it. Now try adding new search entries.

Neil McPartlin
Neil McPartlin
14,662 Points

You're welcome.

I was wondering about the corruption too. If you did all your original coding in Chrome, then tried Safari once and encountered this problem, then that could just have been bad luck with the initial localStorage entry becoming corrupted.

But if you were doing the original coding with Safari, and you did a browser reload while your coding was incomplete, or while the code contained an error which you since fixed, that may explain the cause.