DEV Community

Kailana Kahawaii
Kailana Kahawaii

Posted on

2 1

Creating a Dynamically Controlled Form in React: Additional Parts

In my previous articles, I talked about how to build a dynamically controlled form on the frontend and how to save that data to the backend. In this last installment, I’ll go over the final piece to make this form possible: the API call and additional parts needed.

Posting a recipe

For simplicity’s sake, the API call to post a recipe is stored at the App level.

The constructor holds information for our user as well as our recipes.

constructor() {
    super();
    this.state = {
      auth: {
        user: {},
        recipes: [], 
      }
    };
  }

Data from the form is stored in a newRecipe object. For additional security, the user_id could be changed to something else, such as their access token.

let newRecipe = {
   title: newRecipeState.title,
   summary: newRecipeState.summary,
   ingredients: newRecipeState.ingredients,
   steps: newRecipeState.steps,
   tags: newRecipeState.tags,
   user_id: this.state.auth.user.id
 }

Then, that data is sent to the backend. I use a console.log to verify the data I’m working with when in the testing phase, but this should be taken out for the final product.

 return fetch("http://localhost:3000/api/v1/recipes", {
   method: "POST",
   headers: {
     "Content-Type": "application/json",
     Accept: "application/json",
     Authorization: localStorage.getItem("token")
   },
   body: JSON.stringify(newRecipe)
 })
 .then(resp => resp.json())
 .then(data =>
   console.log(data))
 }

I’ve used the browser router library to display the different components and pass down props and functions in the render method.

<Route
           exact
           path='/add-recipe'
           render={props => <AddRecipeForm {...props} onAddRecipe={this.addRecipe}/>}
         />

Editing a recipe

The editing API call follows similar logic. The recipe’s id is needed to update its information.

 editRecipe = (recipe_id, editRecipeState) => {

   let editedRecipe = {
     title: editRecipeState.title,
     summary: editRecipeState.summary,
     ingredients: editRecipeState.ingredients,
     steps: editRecipeState.steps,
     tags: editRecipeState.tags,
     user_id: this.state.auth.user.id


   }
   return fetch(`http://localhost:3000/api/v1/recipes/${recipe_id}`,{
     method: "PATCH",
     headers: {
       "Content-Type": "application/json",
     Accept: "application/json",
     Authorization: localStorage.getItem("token")
     },
     body: JSON.stringify(editedRecipe)
    }).then(resp => resp.json())
       .then(data =>
         (data))
 }

In addition, the edit route also relies on the id path.

   <Route
           path='/recipes/edit/:id'
           render={props => <EditForm {...props} appState={this.state} onEditRecipe = {this.editRecipe}/>}
           />

Now that we can post and edit a recipe, we ought to be able to view it as well. Although I originally wrote this series to specifically talk about form creation, it’s important to consider how all the pieces work together to create a functional site.

The good news is that viewing the recipes is the most straightforward part of the site. Write a fetch function to populate the state with recipes.

fetchRecipes = () =>{
    api.recipes.getRecipes().then(data => {
      this.setState({
        recipes: data
      })
    })
  }

Tie the fetch to componentDidMouth lifecycle method.

componentDidMount(){
   this.fetchRecipes()
}

In addition, write the logic to render a list of recipes and a single recipe.

 <Route
             exact
             path='/recipes'
             render={props => <RecipeList {...props} appState={this.state}/>}
           />

           <Route
           exact
           path='/recipes/:id'
           render={props => <RecipeDetail {...props} appState={this.state}/>}
           />

Food for thought

I made this before learning about Redux and other state management tools. Hooks, for instance, could also make the codebase much cleaner and manageable. If you’re implementing a pure React app that uses classes, the previous functions provide a good starting point. However, the overall logic for creating a dynamically controlled form should remain the same no matter which tools you use.

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay