Codecademy Store Project - Extra Challenge

Hi,

My store no longer renders after I added the search feature in the extra challenge question. I reviewed my code and searched the boards, but I can’t figure it out. Any ideas as to where I went wrong?

–John

App.js

import React from 'react';
import { Inventory } from '../features/inventory/Inventory.js';
import { CurrencyFilter } from '../features/currencyFilter/CurrencyFilter.js';
// Import the Cart component here.
import { Cart } from '../features/cart/Cart.js';
import { SearchTerm } from '../features/searchTerm/SearchTerm.js';
// Render the Cart component below <Inventory />
export const App = (props) => {

  const { state, dispatch } = props;

  const filteredInventory = getFilteredItems(state.inventory, state.searchTerm);

  return (
    <div>
      <CurrencyFilter
        currencyFilter={state.currencyFilter}
        dispatch={dispatch}
      />

      <Inventory
        inventory={filteredInventory}
        currencyFilter={state.currencyFilter}
        dispatch={dispatch}
      />

      <Cart 
        currencyFilter={state.currencyFilter}
        cart={state.cart}
        dispatch={dispatch}
      />
      
      <SearchTerm 
        SearchTerm={state.searchTerm}
        dispatch={dispatch}
      />
    </div>
  );
};

function getFilteredItems(items, searchTerm) {
  return items.filter(items => items.name.toLowerCase().includes(searchTerm.toLowerCase()));
}

store.js

// Import createStore and combineReducers here.
import { createStore, combineReducers} from 'redux';
// Import the slice reducers here.
import { inventoryReducer } from '../features/inventory/inventorySlice.js';
import { cartReducer } from '../features/cart/cartSlice.js';
import { currencyFilterReducer } from '../features/currencyFilter/currencyFilterSlice.js';
import { searchTermReducer } from '../features/searchTerm/searchTermSlice.js';

// Create and export the store here.
const reducers = {
  inventory: inventoryReducer,
  cart: cartReducer,
  currencyFilter: currencyFilterReducer,
  searchTerm: searchTermReducer
};

const rootReducer = combineReducers(reducers);
export const store = createStore(rootReducer);

SearchTerm.js

import React from 'react';
import { setSearchTerm, clearSearchTerm } from './searchTermSlice.js';

const searchIconUrl =
  'https://static-assets.codecademy.com/Courses/Learn-Redux/Recipes-App/icons/search.svg';
const clearIconUrl =
  'https://static-assets.codecademy.com/Courses/Learn-Redux/Recipes-App/icons/clear.svg';

export const SearchTerm = (props) => {
  const { searchTerm, dispatch } = props;

  const onSearchTermChangeHandler = (e) => {
    const userInput = e.target.value;
    dispatch(setSearchTerm(userInput));
  };

  const onClearSearchTermHandler = () => {
    dispatch(clearSearchTerm());
  };

  return (
    <div id="search-container">
      <img id="search-icon" alt="" src={searchIconUrl} />
      <input
        id="search"
        type="text"
        value={searchTerm}
        onChange={onSearchTermChangeHandler}
        placeholder="Search products"
      />
      {searchTerm.length > 0 && (
        <button
          onClick={onClearSearchTermHandler}
          type="button"
          id="search-clear-button"
        >
          <img src={clearIconUrl} alt="" />
        </button>
      )}
    </div>
  );
};

searchTermSlice

const initialSearchTerm = '';

export const searchTermReducer = (state = initialSearchTerm, action) => {
  switch (action.type) {
    case 'searchTerm/setSearchTerm':
      return action.payload;
    case 'searchTerm/clearSearchTerm':
      return '';
    default: return state;
  };
};

export const setSearchTerm = (term) => {
  return {
    type: 'searchTerm/setSearchTerm',
    payload: term
  }
};

export const clearSearchTerm = () => {
  return {
    type: 'searchTerm/clearSearchTerm'
  }
  };

In case you still have trouble rendering, can you highlight the code that is breaking the store?

Hi Mirja,

Unfortunately, my code is still not rendering.

I have an error in the SearchTerm component, but I didn’t make any changes to the code provided in this file, though it’s possible my code broke something elsewhere that contributed to the error.

The relevant errors I receive are:

This line of code( searchTerm.length > 0 && /#PURE/(0, _jsxRuntime.jsx)(“button”,{) results in the following type error:
Uncaught TypeError: Cannot read properties of undefined (reading ‘length’)

Highlighted Code

var SearchTerm = function SearchTerm(props) {
  var searchTerm = props.searchTerm,
    dispatch = props.dispatch;
  var onSearchTermChangeHandler = function onSearchTermChangeHandler(e) {
    var userInput = e.target.value;
    dispatch((0, _searchTermSlice.setSearchTerm)(userInput));
  };
  var onClearSearchTermHandler = function onClearSearchTermHandler() {
    dispatch((0, _searchTermSlice.clearSearchTerm)());
  };
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    id: "search-container",
    children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
      id: "search-icon",
      alt: "",
      src: searchIconUrl
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
      id: "search",
      type: "text",
      value: searchTerm,
      onChange: onSearchTermChangeHandler,
      placeholder: "Search products"
    }), **searchTerm.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {**
      onClick: onClearSearchTermHandler,
      type: "button",
      id: "search-clear-button",
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
        src: clearIconUrl,
        alt: ""
      })
    })]
  });
};

Thanks.

–John

I always used the reduxjs/toolkit when working with redux, so I’m not very familiar with this syntax.
Have you logged searchTerm?
My idea is that it is not an empty string but undefined when destructured from props. Then it would not have a property .length which breaks your code. But I don’t see any obvious errors.

2 Likes

Difficult to identify issues when one can only read but not experiment with code.

But a couple of questions:

  • In App.js, is there a reason why the getFilteredItems function is at the bottom? In its current position, it seems to be outside the App component. If you move it just above the return, does it make any difference?

  • As noted by the error message and as suggested by mirja_t, it seems that .length is being called on something undefined. The only line in your code which has .length is in SearchTerm.js specifically the line

{searchTerm.length > 0 && ( ...

Earlier in SearchTerm.js, you have the destructuring

const { searchTerm, dispatch } = props;

Now, shifting to App.js where the props are actually being provided to the SearchTerm instance, we have:

<SearchTerm 
     SearchTerm={state.searchTerm}
     dispatch={dispatch}
/>

In your destructuring, you are expecting props to have the properties named dispatch and searchTerm. But, in App.js when actually providing the props, your properties are named dispatch and SearchTerm. I suspect that is why you are seeing undefined.
Try changing it to:

<SearchTerm 
     searchTerm={state.searchTerm}
     dispatch={dispatch}
/>
3 Likes

You are correct. I accidentally capitalized searchTerm when passing in the props via App.js. It works perfectly now.

Thanks again for reviewing the code!

–John

1 Like