1

I get error "Uncaught TypeError: recipeList.push is not a function" when i try to submit data to localStorage. If i dont push but just rewrite existing data withouth using push() then i get no errors. I think this should be some newbie mistake.

AddRecipe.js page looks like this

  import { useNavigate } from "react-router-dom";

import NewRecipeForm from "../components/recipes/NewRecipeForm";

const AddRecipe = () => {
  const Navigate = useNavigate();

  const setLocalStorage = (recipe) => {
    const recipeList = JSON.parse(localStorage.getItem("recipe")) || [];

    recipeList.push(recipe);
    localStorage.setItem("recipe", JSON.stringify(recipeList));
    Navigate("/");
  };

  // const RecipeFormHandler = (recipeData) => {
  //   localStorage.setItem("recipe", JSON.stringify(recipeData));

  //   Navigate("/");
  // };

  return (
    <section>
      <NewRecipeForm onAddRecipe={setLocalStorage} />
    </section>
  );
};

export default AddRecipe;

NewRecipeForm.js looks like this and i am trying to save recipeData to localStorage

import classes from "./NewRecipeForm.module.css";
import Card from "../ui/Card";
import { useRef } from "react";

const NewRecipeForm = (props) => {
  const titleRef = useRef();
  const imgRef = useRef();
  const ingredientsRef = useRef();
  const descriptionRef = useRef();

  function submitHandler(event) {
    event.preventDefault();

    const enteredTitle = titleRef.current.value;
    const enteredImg = imgRef.current.value;
    const enteredingredients = ingredientsRef.current.value;
    const enteredDescription = descriptionRef.current.value;

    const recipeData = {
      id: (Math.random() * 100).toString(),
      title: enteredTitle,
      image: enteredImg,
      ingredients: enteredingredients,
      description: enteredDescription,
    };

    props.onAddRecipe(recipeData);
  }

  return (
    <Card>
      <form className={classes.form} onSubmit={submitHandler}>
        <div className={classes.control}>
          <label htmlFor="title">Recipe Name</label>
          <input type="text" required id="title" ref={titleRef} />
        </div>
        <div className={classes.control}>
          <label htmlFor="image">Recipe Image</label>
          <input type="url" required id="image" ref={imgRef} />
        </div>
        <div className={classes.control}>
          <label htmlFor="ingredients">Ingredients</label>
          <textarea
            type="text"
            required
            id="ingredients"
            rows="5"
            ref={ingredientsRef}
          />
        </div>
        <div className={classes.control}>
          <label htmlFor="description">Description</label>
          <textarea id="description" required rows="5" ref={descriptionRef} />
        </div>
        <div className={classes.actions}>
          <button type="reset">Reset</button>
          <button type="submit">Add Recipe</button>
        </div>
      </form>
    </Card>
  );
};

export default NewRecipeForm;

2
  • please print the output of localStorage.getItem("recipe") Commented Jan 12, 2022 at 19:03
  • The const recipelist probaly is been seted with the data of the localStorage, try to console the const Commented Jan 12, 2022 at 19:05

1 Answer 1

0

I just used strings instead of Ref's. The replication of it got me to the working SHORT code here: SandBox.
NewRecipeForm.js

import { NewRecipeForm } from "./Child";

export default function App() {
  const setLocalStorage = (recipe) => {
    const recipeList = JSON.parse(localStorage.getItem("recipe")) || [];

    recipeList.push(recipe);
    localStorage.setItem("recipe", JSON.stringify(recipeList));
    console.log(recipeList);
  };
  return (
    <div className="App">
      <NewRecipeForm onAddRecipe={setLocalStorage} />
    </div>
  );
}

Child.js

export const NewRecipeForm = (props) => {
  function submitHandler(event) {
    const recipeData = {
      id: (Math.random() * 100).toString(),
      title: "enteredTitle",
      image: "enteredImg",
      ingredients: "enteredingredients",
      description: "enteredDescription"
    };

    props.onAddRecipe(recipeData);
  }
  return <button onClick={() => submitHandler()}>Click to print</button>;
};

Not the answer you're looking for? Browse other questions tagged or ask your own question.