У меня есть проект django / реагировать (s3 bucket для загрузки изображений), который добавляет рецепты в базу данных postgres.В моем компоненте RecipeFormContainer одно из моих свойств к рецептуре - это массив ингредиентов.Предполагается, что массив будет заполнен объектами, которые состоят из пар ключ-значение, единиц, количества и т. Д. Я написал метод addIngredients, но, похоже, он не добавляет объекты в мой массив ингредиентов.Я получаю ошибку "ингридиенты: [" Это поле обязательно для заполнения. "]" При попытке отправить мой рецепт и сделать сообщение.Пожалуйста, просветите меня тем, чего мне не хватает.Код выглядит следующим образом:
import React, {Component} from 'react';
import {Form} from 'react-bootstrap'
import Button from 'react-bootstrap/Button';
class RecipeFormContainer extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
creator: '',
mealTime: "",
prepTime: "",
cookTime: "",
image_preview: "",
servings: "",
directions: '',
ingredients: [{
units: '',
amounts: '',
multiples: '',
quantity: '',
name: ''
}],
image: "",
};
this.handleImage = this.handleImage.bind(this);
this.handleIngredientInput = this.handleIngredientInput.bind(this);
this.handleAddIngredients = this.handleAddIngredients.bind(this);
}
handleAddIngredients =(e) => {
e.preventDefault();
// the ingredients properties are not being added to the ingredients array property on state *************************
let ingredient = {units: '',
amounts: '',
multiples: '',
quantity: '',
name: ''};
//save the current state of ingredients array in variable ingredient
let {ingredients} = this.state.ingredients;
// add the ingredient object into the ingredients array ( which is a property of state)
ingredients.push(ingredient);
// set the new array of ingredients as the state of the property ingredients
this.setState( {ingredients: ingredients});
};
handleInput = (e) => {
e.preventDefault();
this.setState({[e.target.name]: e.target.value});
};
handleIngredientInput = (e) => {
e.preventDefault();
this.setState({[e.target.name]: e.target.value})
};
handleImage(event) {
event.preventDefault();
// this makes it show up in preview
let file = event.target.files[0];
let fileReader = new FileReader();
fileReader.onloadend = () => this.setState({image_preview:fileReader.result});
fileReader.readAsDataURL(file);
this.setState({image:file});
}
submitRecipe = (event) => {
event.preventDefault();
let recipe = {...this.state};
console.log('recipe one', this.state);
let formData = new FormData();
formData.append("image", this.state.image);
formData.append('title', this.state.title);
formData.append("ingredients", this.state.ingredients);
formData.append("mealTime", this.state.mealTime);
formData.append("prepTime", this.state.prepTime);
formData.append("cookTime", this.state.cookTime);
formData.append("image_Preview", this.state.image_preview);
formData.append("servings", this.state.servings);
formData.append("directions", this.state.directions);
formData.append("creator", this.state.creator);
// formData.append("units", this.state.ingredients.units);
// formData.append("amount", this.state.ingredients.amount);
// formData.append("multiples", this.state.ingredients.multiples);
// formData.append("quantity", this.state.ingredients.quantity);
// formData.append("name", this.state.ingredients.name);
// add line for each property of state
const conf = {
method: "POST",
body: formData,
};
fetch('/api/recipe/', conf).then((response) => {
return response.json();
}).then((json) => {
this.props.addRecipe(json);
});
};
render() {
return (
<Form onSubmit={this.submitRecipe} encType="multipart/form-data" >
<Form.Group onSubmit={event => {event.preventDefault(); }} >
<img src={this.state.image_preview}/>
<input className="input" type="file" onChange={this.handleImage} name="image" />
</Form.Group>
<Form.Group controlId="exampleForm.ControlInput1">
<Form.Label>Recipe Name</Form.Label>
<Form.Control type="text" placeholder="Enter Recipe Name Here"
name="title"
value={this.state.title}
onChange={this.handleInput}/>
<Form.Label>Recipe Creator</Form.Label>
<Form.Control type="text" placeholder="Enter Your Name Here"
value={this.state.creator}
name="creator"
onChange={this.handleInput}/>
</Form.Group>
<Form.Group controlId="exampleForm.ControlSelect1" id="foodType">
<Form.Label>Example select</Form.Label>
<Form.Control as="select">
<option>Breakfast</option>
<option>Lunch</option>
<option>Dinner</option>
<option>Dessert</option>
<option>Vegetarian</option>
</Form.Control>
</Form.Group>
<Form.Control type="text" placeholder="Prep Time" className="midButt"
value={this.state.prepTime}
name="prepTime"
onChange={this.handleInput}/>
<Form.Control type="text" placeholder="Cook Time" className="midButt"
value={this.state.cookTime}
name="cookTime"
onChange={this.handleInput}/>
<Form.Group controlId="exampleForm.ControlSelect1" id="foodTemp">
<Form.Control as="select">
<option>Fahrenheit</option>
<option>Celsius</option>
</Form.Control>
</Form.Group>
<Form.Group>
This Recipe Will Make: <Form.Control type="number" placeholder="servings" id="servings" value={this.state.ingredients.servings} onChange={this.handleInput} name="servings" />
<Form.Control type="text" placeholder="cookies, loaves, etc." id="loaf" value={this.state.ingredients.multiples} onChange={this.handleIngredientInput} name="multiples"/>
</Form.Group>
{this.state.ingredients.map((ingredient, index) => {
return (
<div key={index}>
<Form.Control type="number" placeholder="#" id="numberAmount" value={this.state.ingredients.quantity} onChange={this.handleIngredientInput} name="amount"/>
<Form.Control type="text" placeholder="units" id="units" value={this.state.ingredients.units} onChange={this.handleIngredientInput} name="units"/>
<Form.Control type="text" placeholder="Ingredient Name" id="name" value={this.state.ingredients.name} onChange={this.handleIngredientInput} name="name"/>
</div>
);
})};
<Button variant="light" onClick = {this.handleAddIngredients}> + </Button>
{/*/!*will update state with event handler this.state.ingredients, append object to array *!/*/}
<Form.Group controlId="exampleForm.ControlTextarea1">
<Form.Label>Directions</Form.Label>
<Form.Control as="textarea" rows="3"
value={this.state.directions}
name="directions"
onChange={this.handleInput}/>
</Form.Group>
<Button type="submit" variant="secondary">Save This Recipe !</Button>
</Form>
)
};
}
export default RecipeFormContainer;