title: Problem with error Cannot read property 'slice' of undefined
body: <p>I get this error</p>
  
  <pre><code>TypeError: Cannot read property 'slice' of undefined
      at Object.renderResults (searchView.js:93)
      at _callee$ (index.js:85)
      at tryCatch (runtime.js:65)
      at Generator.invoke [as _invoke] (runtime.js:303)
      at Generator.prototype.(:8081/anonymous function) [as next] (webpack:///./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js?:117:21)
      at step (index.js:41)
      at eval (index.js:41)
  </code></pre>
  
  <p>after searching for let's say 'pizza' in the search bar in my project, it's my github repo: <a href="https://github.com/damianjnc/finalforkify" rel="nofollow noreferrer">https://github.com/damianjnc/finalforkify</a></p>
  
  <p>I believe there might be an error in this part of the code:</p>
  
  <pre><code>export const renderResults = (recipes, page = 1, resPerPage = 10) =&gt; {
      // render results of currente page
      const start = (page - 1) * resPerPage;
      const end = page * resPerPage;
  
      recipes.slice(start, end).forEach(recipe =&gt; renderRecipe(recipe));
  
      // render pagination buttons
      renderButtons(page, recipes.length, resPerPage);
  };
  </code></pre>
  
  <p>in file searchView.js: 
  <div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { elements } from './base';
  
  export const getInput = () =&gt; elements.searchInput.value;
  
  export const clearInput = () =&gt; {
      elements.searchInput.value = '';
  };
  
  export const clearResults = () =&gt; {
      elements.searchResList.innerHTML = '';
      elements.searchResPages.innerHTML = '';
  };
  
  export const highlightSelected = id =&gt; {
      const resultsArr = Array.from(document.querySelectorAll('.results__link'));
      resultsArr.forEach(el =&gt; {
          el.classList.remove('results__link--active');
      });
      document.querySelector(`.results__link[href*="${id}"]`).classList.add('results__link--active');
  };
  
  /*
  // 'Pasta with tomato and spinach'
  acc: 0 / acc + cur.length = 5 / newTitle = ['Pasta']
  acc: 5 / acc + cur.length = 9 / newTitle = ['Pasta', 'with']
  acc: 9 / acc + cur.length = 15 / newTitle = ['Pasta', 'with', 'tomato']
  acc: 15 / acc + cur.length = 18 / newTitle = ['Pasta', 'with', 'tomato']
  acc: 18 / acc + cur.length = 24 / newTitle = ['Pasta', 'with', 'tomato']
  */
  export const limitRecipeTitle = (title, limit = 17) =&gt; {
      const newTitle = [];
      if (title.length &gt; limit) {
          title.split(' ').reduce((acc, cur) =&gt; {
              if (acc + cur.length &lt;= limit) {
                  newTitle.push(cur);
              }
              return acc + cur.length;
          }, 0);
  
          // return the result
          return `${newTitle.join(' ')} ...`;
      }
      return title;
  }
  
  const renderRecipe = recipe =&gt; {
      const markup = `
          &lt;li&gt;
              &lt;a class="results__link" href="#${recipe.recipe_id}"&gt;
                  &lt;figure class="results__fig"&gt;
                      &lt;img src="${recipe.image_url}" alt="${recipe.title}"&gt;
                  &lt;/figure&gt;
                  &lt;div class="results__data"&gt;
                      &lt;h4 class="results__name"&gt;${limitRecipeTitle(recipe.title)}&lt;/h4&gt;
                      &lt;p class="results__author"&gt;${recipe.publisher}&lt;/p&gt;
                  &lt;/div&gt;
              &lt;/a&gt;
          &lt;/li&gt;
      `;
      elements.searchResList.insertAdjacentHTML('beforeend', markup);
  };
  
  // type: 'prev' or 'next'
  const createButton = (page, type) =&gt; `
      &lt;button class="btn-inline results__btn--${type}" data-goto=${type === 'prev' ? page - 1 : page + 1}&gt;
          &lt;span&gt;Page ${type === 'prev' ? page - 1 : page + 1}&lt;/span&gt;
          &lt;svg class="search__icon"&gt;
              &lt;use href="img/icons.svg#icon-triangle-${type === 'prev' ? 'left' : 'right'}"&gt;&lt;/use&gt;
          &lt;/svg&gt;
      &lt;/button&gt;
  `;
  
  const renderButtons = (page, numResults, resPerPage) =&gt; {
      const pages = Math.ceil(numResults / resPerPage);
  
      let button;
      if (page === 1 &amp;&amp; pages &gt; 1) {
          // Only button to go to next page
          button = createButton(page, 'next');
      } else if (page &lt; pages) {
          // Both buttons
          button = `
              ${createButton(page, 'prev')}
              ${createButton(page, 'next')}
          `;
      } else if (page === pages &amp;&amp; pages &gt; 1) {
          // Only button to go to prev page
          button = createButton(page, 'prev');
      }
  
      elements.searchResPages.insertAdjacentHTML('afterbegin', button);
  };
  
  export const renderResults = (recipes, page = 1, resPerPage = 10) =&gt; {
      // render results of currente page
      const start = (page - 1) * resPerPage;
      const end = page * resPerPage;
  
      recipes.slice(start, end).forEach(recipe =&gt; renderRecipe(recipe));
  
      // render pagination buttons
      renderButtons(page, recipes.length, resPerPage);
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p>The code which calls <code>renderResults</code> function is in <code>index.js</code> file. Here is that part of the code:</p>
  
  <pre><code>/** 
   * SEARCH CONTROLLER
   */
  const controlSearch = async () =&gt; {
      // 1) Get query from view
      const query = searchView.getInput();
  
      if (query) {
          // 2) New search object and add to state
          state.search = new Search(query);
  
          // 3) Prepare UI for results
          searchView.clearInput();
          searchView.clearResults();
          renderLoader(elements.searchRes);
  
          try {
              // 4) Search for recipes
              await state.search.getResults();
  
              // 5) Render results on UI
              clearLoader();
              searchView.renderResults(state.search.result);
          } catch (err) {
              console.log(err);
              alert('Something wrong with the search...');
              clearLoader();
          }
      }
  }
  
  elements.searchForm.addEventListener('submit', e =&gt; {
      e.preventDefault();
      controlSearch();
  });
  </code></pre>
  
  <p>and full index.js file:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import Search from './models/Search';
  import Recipe from './models/Recipe';
  import List from './models/List';
  import Likes from './models/Likes';
  import * as searchView from './views/searchView';
  import * as recipeView from './views/recipeView';
  import * as listView from './views/listView';
  import * as likesView from './views/likesView';
  import { elements, renderLoader, clearLoader } from './views/base';
  
  /** Global state of the app
   * - Search object
   * - Current recipe object
   * - Shopping list object
   * - Liked recipes
   */
  const state = {};
  
  /** 
   * SEARCH CONTROLLER
   */
  const controlSearch = async () =&gt; {
      // 1) Get query from view
      const query = searchView.getInput();
  
      if (query) {
          // 2) New search object and add to state
          state.search = new Search(query);
  
          // 3) Prepare UI for results
          searchView.clearInput();
          searchView.clearResults();
          renderLoader(elements.searchRes);
  
          try {
              // 4) Search for recipes
              await state.search.getResults();
      
              // 5) Render results on UI
              clearLoader();
              searchView.renderResults(state.search.result);
          } catch (err) {
              console.log(err);
              alert('Something wrong with the search...');
              clearLoader();
          }
      }
  }
  
  elements.searchForm.addEventListener('submit', e =&gt; {
      e.preventDefault();
      controlSearch();
  });
  
  
  elements.searchResPages.addEventListener('click', e =&gt; {
      const btn = e.target.closest('.btn-inline');
      if (btn) {
          const goToPage = parseInt(btn.dataset.goto, 10);
          searchView.clearResults();
          searchView.renderResults(state.search.result, goToPage);
      }
  });
  
  
  /** 
   * RECIPE CONTROLLER
   */
  const controlRecipe = async () =&gt; {
      // Get ID from url
      const id = window.location.hash.replace('#', '');
  
      if (id) {
          // Prepare UI for changes
          recipeView.clearRecipe();
          renderLoader(elements.recipe);
  
          // Highlight selected search item
          if (state.search) searchView.highlightSelected(id);
  
          // Create new recipe object
          state.recipe = new Recipe(id);
  
          try {
              // Get recipe data and parse ingredients
              await state.recipe.getRecipe();
              state.recipe.parseIngredients();
  
              // Calculate servings and time
              state.recipe.calcTime();
              state.recipe.calcServings();
      
              // Render recipe
              clearLoader();
              recipeView.renderRecipe(
                  state.recipe,
                  state.likes.isLiked(id)
              );
  
          } catch (err) {
              console.log(err);
              alert('Error processing recipe!');
          }
      }
  };
   
  ['hashchange', 'load'].forEach(event =&gt; window.addEventListener(event, controlRecipe));
  
  
  /** 
   * LIST CONTROLLER
   */
  const controlList = () =&gt; {
      // Create a new list IF there in none yet
      if (!state.list) state.list = new List();
  
      // Add each ingredient to the list and UI
      state.recipe.ingredients.forEach(el =&gt; {
          const item = state.list.addItem(el.count, el.unit, el.ingredient);
          listView.renderItem(item);
      });
  }
  
  // Handle delete and update list item events
  elements.shopping.addEventListener('click', e =&gt; {
      const id = e.target.closest('.shopping__item').dataset.itemid;
  
      // Handle the delete button
      if (e.target.matches('.shopping__delete, .shopping__delete *')) {
          // Delete from state
          state.list.deleteItem(id);
  
          // Delete from UI
          listView.deleteItem(id);
  
      // Handle the count update
      } else if (e.target.matches('.shopping__count-value')) {
          const val = parseFloat(e.target.value, 10);
          state.list.updateCount(id, val);
      }
  });
  
  
  /** 
   * LIKE CONTROLLER
   */
  const controlLike = () =&gt; {
      if (!state.likes) state.likes = new Likes();
      const currentID = state.recipe.id;
  
      // User has NOT yet liked current recipe
      if (!state.likes.isLiked(currentID)) {
          // Add like to the state
          const newLike = state.likes.addLike(
              currentID,
              state.recipe.title,
              state.recipe.author,
              state.recipe.img
          );
          // Toggle the like button
          likesView.toggleLikeBtn(true);
  
          // Add like to UI list
          likesView.renderLike(newLike);
  
      // User HAS liked current recipe
      } else {
          // Remove like from the state
          state.likes.deleteLike(currentID);
  
          // Toggle the like button
          likesView.toggleLikeBtn(false);
  
          // Remove like from UI list
          likesView.deleteLike(currentID);
      }
      likesView.toggleLikeMenu(state.likes.getNumLikes());
  };
  
  // Restore liked recipes on page load
  window.addEventListener('load', () =&gt; {
      state.likes = new Likes();
      
      // Restore likes
      state.likes.readStorage();
  
      // Toggle like menu button
      likesView.toggleLikeMenu(state.likes.getNumLikes());
  
      // Render the existing likes
      state.likes.likes.forEach(like =&gt; likesView.renderLike(like));
  });
  
  
  // Handling recipe button clicks
  elements.recipe.addEventListener('click', e =&gt; {
      if (e.target.matches('.btn-decrease, .btn-decrease *')) {
          // Decrease button is clicked
          if (state.recipe.servings &gt; 1) {
              state.recipe.updateServings('dec');
              recipeView.updateServingsIngredients(state.recipe);
          }
      } else if (e.target.matches('.btn-increase, .btn-increase *')) {
          // Increase button is clicked
          state.recipe.updateServings('inc');
          recipeView.updateServingsIngredients(state.recipe);
      } else if (e.target.matches('.recipe__btn--add, .recipe__btn--add *')) {
          // Add ingredients to shopping list
          controlList();
      } else if (e.target.matches('.recipe__love, .recipe__love *')) {
          // Like controller
          controlLike();
      }
  });</code></pre>
  </div>
  </div>
  </p>