import React ,{useContext, useState, useEffect} from 'react'
import axios from 'axios'
import {Container,Form,Row,Col,Figure,Table,Card,ListGroup, Spinner,Badge, Accordion,Button} from 'react-bootstrap'
import ImageUpload from '../../shared/components/FormElements/ImageUpload'
import Input from '../../shared/components/FormElements/Input'
import {useForm} from '../../shared/hooks/form-hooks'
import {VALIDATOR_MINLENGTH,VALIDATOR_EMAIL, VALIDATOR_REQUIRE} from '../../shared/util/validators'
import './NewRecipe.css'
import Ingredient from './Ingredient'
import Instruction from './Instruction'
import {AuthContext} from '../../shared/context/auth-context'
const NewRecipe = props => {
const auth = useContext(AuthContext)
const [formState,inputHandler, setFormData]= useForm({
title:{
value:"",
isValid:false
},
image:{
value:null,
isValid:false
},
readyInMinutes:{
value:"",
isValid:false
},
servings:{
value:"",
isValid:false
},
price:{
value:"",
isValid:false
},
ingredients:[{
name:{
value:"",
isValid:false
},
amount:{
value:"",
isValid:false
},
measure:{
value:"",
isValid:false
}
}
],
instructions:[
{
content:{
value:"",
isValid:false
}
}
]
},false)
const [ingredients,setIngredients] = useState([])
const [ingredientCount,setIngredientCount] = useState(0)
const [instructionCount, setInstructionCount] = useState(0)
const [instructions, setInstructions] = useState([])
const addIngredient = () => {
setIngredientCount(ingredientCount=> ingredientCount + 1)
setIngredients(prev => [...prev,ingredientCount])
}
const addInstruction = () => {
setInstructionCount(instructionCount => instructionCount + 1)
setInstructions(prev => [...prev, instructionCount])
}
const handleIngredientRemove = (index) => {
setIngredients(ingredients.filter(ingredient => ingredient !== index))
setIngredientCount(ingredientCount => ingredientCount - 1)
}
const handleInstructionRemove = (index) => {
setInstructions(ingredients.filter(ingredient => ingredient !== index))
setInstructionCount(ingredientCount => ingredientCount - 1)
}
const handleSubmit = (e) => {
e.preventDefault()
setFormData({...formState.inputs},false)
try{
console.log(formState.inputs)
const formData = new FormData()
const my_ingredients = new Array()
const my_instructions = new Array()
my_ingredients.push({name:formState.inputs.iName.value,amount:parseFloat(formState.inputs.amount.value),measure:formState.inputs.measure.value})
console.log(my_ingredients)
my_instructions.push({content:formState.inputs.content.value})
formData.append('title',formState.inputs.title.value)
formData.append('readyInMinutes',parseFloat(formState.inputs.readyInMinutes.value))
formData.append('servings',parseFloat(formState.inputs.servings.value))
formData.append('price',parseFloat(formState.inputs.price.value))
formData.append('ingredients',JSON.stringify(my_ingredients))
formData.append('instructions',JSON.stringify(my_instructions))
formData.append('image',formState.inputs.image.value)
console.log(formData.get('ingredients'))
console.log(formData.get('instructions'))
console.log(formData.get('image'))
console.log(formData.get('price'))
console.log(formData.get('servings'))
console.log(formData.get('title'))
const responseData = axios.post(
process.env.REACT_APP_BACKEND_URL+'/recipes/new',
formData,{
headers: {"Authorization" : `Bearer ${auth.token}`} })
console.log(responseData)
console.log('2g')
}
catch(err){
console.log(err.message)
}
}
return (
<div className='recipe-main'>
<h3>-</h3>
<Container className='new-recipe-container' >
<Card border="secondary" className='recipe-form'>
<Form className='form-container' >
<Input
element='input'
type='text'
id='title'
name='title'
label='Title'
validators={[VALIDATOR_REQUIRE()]}
errorText='Please enter a title...'
placeholder='Please enter a title...'
onInput={inputHandler} />
<Input
element='input'
type='number'
id='readyInMinutes'
name='readyInMinutes'
label='ReadyInMinutes'
validators={[VALIDATOR_REQUIRE()]}
errorText='Please enter a readyInMinutes...'
placeholder='Please enter a readyInMinutes...'
onInput={inputHandler} />
<ImageUpload
id='image'
name='image'
validators={[VALIDATOR_REQUIRE()]}
errorText='Please import an image file.'
onInput={inputHandler}
/>
<Button className='increment-btn' variant="warning" size="lg" block onClick={addIngredient}>
Add Ingredient
</Button>
{ingredients.map(index => {
return ( <Ingredient key={index} onInputHandler={inputHandler} deleteIngredientHandler={() => handleIngredientRemove(index)} iId={index} />)
}
)}
<Input
element='input'
type='number'
id='servings'
name='servings'
label='Servings'
validators={[VALIDATOR_REQUIRE()]}
errorText='Please enter a servings...'
placeholder='Please enter a servings...'
onInput={inputHandler} />
<Input
element='input'
type='number'
id='price'
name='price'
label='Price'
validators={[VALIDATOR_REQUIRE()]}
errorText='Please enter a price...'
placeholder='Please enter a price...'
onInput={inputHandler} />
<Button className='increment-btn' variant="warning" size="lg" block onClick={addInstruction}>
Add Instruction
</Button>
{instructions.map(index => {
return <Instruction key={index} iId={index} onInputHandler={inputHandler} deleteInstruction={() => handleInstructionRemove(index)} />
})}
<Button type='submit' className='submit-btn' size="lg" block onClick={handleSubmit}>Add Recipe</Button>
</Form>
</Card>
</Container>
</div>
)
}
export default NewRecipe
Я хотел бы объявить мои составные / форматы данных с топором ios post и authenticatiomn. Я не получаю никакой ошибки аутентификации, но я получаю 500 кодов состояния для сервера. По сути, у меня есть свой собственный API и я хочу опубликовать данные в моем собственном API. Я застрял в этом. Спасибо за вашу помощь. введите описание изображения здесь
модель рецепта
const mongoose = require('mongoose')
const uniqueValidator = require('mongoose-unique-validator')
const commentSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true
},
content: {
type: String,
required: true,
maxLength: 280
}
}, {
timestamps: true, // this adds `createdAt` and `updatedAt` properties
toJSON: {
// whenever the comment is converted to JSON
transform(doc, json) {
delete json.__v
return json
}
}
})
const recipeSchema = new mongoose.Schema({
title:{
type:String,
required:true
},
image:{
type:String,
required:true
},
ingredients:[{
name:{
type:String,
required:true
},
image:{
type:String,
required:true
},
amount:{
type:Number,
required:true
},
measure:{
type:String,
required:true
}
}],
instructions:[{
content:{
type:String,
required:true
}
}],
readyInMinutes:{
type:Number,
required:true
},
servings:{
type:Number,
required:true
},
ratings:[{
point:{
type:Number,
required:true
}
}],
creator:{
type:mongoose.Types.ObjectId,
required:true,
ref:'User'
},
comments:[commentSchema],
nutrients:[{
name:{
type:String,
required:true
},
amount:{
type:Number,
required:true
}
}],
price:{
type:Number,
required:true
}
})
recipeSchema.plugin(uniqueValidator) //We plugin wiht mogooseValidator with our schema.
module.exports = mongoose.model('Recipe',recipeSchema) //We called User model with recipeSchema
рецепт колокольчика. js
const HttpError = require('../models/HttpError')
const bcrypt = require('bcryptjs')
const jwt= require('jsonwebtoken')
const Recipe = require('../models/Recipe')
const User = require('../models/User')
const {validationResult} = require('express-validator')
const mongoose = require('mongoose')
const uuid = require('uuid/v4')
const fs = require('fs')
const path = require('path')
const getAllRecipes = async (req, res, next) => { //We get all recipes to show users' recipes
let recipes
try{
recipes = await Recipe.find({}).exec()
}
catch(err){
const error = new HttpError('Something went wrong',500)
return next(error)
}
if(!recipes){
const error = new HttpError('Could not find any recipe',404)
return next(error)
}
res.status(200).json({recipes:recipes.map(recipe => recipe.toObject({getters:true}))})
}
const getRecipesByUserId = async (req, res, next) => { // We want to get recipes by userId, so we can show user's recipes
const userId = req.params.uid
let existingUser
try{
existingUser = await User.findById(userId).populate('recipes')
}
catch(err){
const error = new HttpError('Could not find any recipes provided user id',500)
return next(error)
}
if(!existingUser){ // We check if this user exist or not in our database.
const error = new HttpError('Could not find any user provided user id',404)
return next(error)
}
res.status(200).json({recipes:existingUser.recipes.map(recipe => recipe.toObject({getters:true}))})
}
const createRecipe = async (req, res, next) =>{ //We create a new recipe
const errors = validationResult(req)
if(!errors.isEmpty()){
const error = new HttpError('Invalid inputs passed, please check your data.',422)
return next(error)
}
const {title,ingredients,instructions,readyInMinutes, servings, ratings,comments, nutrients,price} = req.body
const createdRecipe = new Recipe({
title,
image:req.file.path,
ingredients,
instructions,
readyInMinutes,
servings,
ratings:[],
creator:req.userData.userId,
comments:[],
nutrients:[],
price
})
let user
try{
user = await User.findById(req.userData.userId) // When we add a new recipe we need user's recipes array,too.That's why We need user who add this recipe.
}
catch(err){
const errors = new HttpError('Something went wrong',500)
return next(error)
}
if(!user){
const error = new HttpError('This user does not exist',422)
return next(error)
}
try{ // We need to do this.Because When we add a new recipe that affect user's recipes array, too.We want to make sure to add this recipe both collections.
const sess = await mongoose.startSession()
sess.startTransaction()
await createdRecipe.save({session:sess})
user.recipes.push(createdRecipe)
await user.save({session:sess})
await sess.commitTransaction()
}
catch(err){
const error = new HttpError('Created recipe failed, please create again',500)
return next(error)
}
res.status(201).json({recipe:createdRecipe})
}
const updateRecipe = async (req, res, next) => {
const errors = validationResult(req)
if(!errors.isEmpty()){
const error = new HttpError('Invalid inputs passed, please check your data.',422)
return next(error)
}
const recipeId = req.params.rid
let existingRecipe
try
{
existingRecipe = await Recipe.findById(recipeId).populate('creator')
}
catch(err){
const error = new HttpError('Something went wrong could not update place', 500)
return next(error)
}
if(existingRecipe.creator.id !== req.userData.userId){ // We want to know that creator and currentUser same person or not.
const error = new HttpError('You are not allowed to update this recipe ',403)
return next(error)
}
const {title,ingredients,instructions,readyInMinutes, servings, nutrients,price} = req.body
existingRecipe.title = title
existingRecipe.image = req.file.path
existingRecipe.ingredients= ingredients
existingRecipe.instructions = instructions
existingRecipe.readyInMinutes = readyInMinutes
existingRecipe.servings = servings
existingRecipe.nutrients = nutrients
existingRecipe.price = price
try{
await existingRecipe.save()
}
catch(err){
const error = new HttpError('Something went wrong could not update recipe', 500)
return next(error)
}
res.status(200).json({recipe:existingRecipe.toObject({getters:true})})
}
const deleteRecipe = async (req, res, next) => {
const recipeId = req.params.rid
let recipe
try{
recipe = await Recipe.findById(recipeId).populate('creator')
}
catch(err){
const error = new HttpError('Something went wrong',500)
return next(error)
}
if(!recipe){
const error = new HttpError('This recipe does not exist',404)
return next(error)
}
if(recipe.creator.id !== req.userData.userId){ // We want to know that creator and currentUser same person or not.
const error = new HttpError('You are not allowed to delete this recipe',403)
return next(error)
}
const imagePath = recipe.image
try{
const sess = await mongoose.startSession()
sess.startTransaction()
await recipe.remove({session:sess})
recipe.creator.recipes.pull(recipe)
await recipe.creator.save({session:sess})
await sess.commitTransaction()
}
catch(err){
const error = new HttpError('Something went me wrong',500)
return next(error)
}
fs.unlink(imagePath, err => {
console.log(err);
})
res.status(200).json({message:'Deleted recipe'})
}
exports.getAllRecipes = getAllRecipes
exports.getRecipesByUserId = getRecipesByUserId
exports.createRecipe = createRecipe
exports.updateRecipe = updateRecipe
exports.deleteRecipe = deleteRecipe
![enter image description here](https://i.stack.imgur.com/Ta6Pn.png)
Вот моя вкладка newtwork инструментов разработчика с заголовками моих запросов