I have a problem with my code. I have a tag with options, when I try to set contact type set contact type appears white screen with error in the console "types.map() is not a function" white screen with errors. I think the problem comes from that at the beginning "types" are array and when I choose contact type with the state() "types" become a single value. I don't know how to fix that.
This is my code:
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import styles from './postContact.module.css';
const PostContact = () => {
const [nickName, setNickName] = useState('');
const [address, setAddress] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [account, setAccount] = useState('');
const [types, setType] = useState([]);
const navigate = useNavigate();
const postContact = async (e) => {
e.preventDefault();
await fetch('http://localhost:5090/api/contacts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
nickName,
address,
phoneNumber,
userId: 1,
contactTypeId: types,
account
})
})
.then(() => {
navigate('/');
})
.catch((e) => {
alert(e.message)
});
};
const getTypes = async () => {
const request = await fetch('http://localhost:5090/api/contactTypes', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const response = await request.json();
setType(response);
};
useEffect(() => {
getTypes();
}, []);
return (
<form className={styles['post-form']} onSubmit={postContact}>
<label htmlFor='nickName'>Nickname</label>
<input className={styles.input} id='nickName' type='text' onChange={e => setNickName(e.target.value)} value={nickName} />
<label htmlFor='address'>Address</label>
<textarea className={styles.input} id='address' type='text' onChange={e => setAddress(e.target.value)} value={address} />
<label htmlFor='phoneNumber'>Phone Number</label>
<input className={styles.input} id='phoneNumber' type='text' onChange={e => setPhoneNumber(e.target.value)} value={phoneNumber} />
<label htmlFor='account'>Account</label>
<input className={styles.input} id='account' type='text' onChange={e => setAccount(e.target.value)} value={account} />
<label htmlFor="type">Contact Type</label>
<select className={styles.input} title="type" name="type" onChange={e => setType(e.target.value)} value={types}>
{types.map(type=>
<option key={type.id} value={type.id}>{type.type}</option>
)}
</select>
<button className="btn btn-primary mt-5" type='submit' name='Post'>Create</button>
</form>
);
};
export default PostContact;
I'll be grateful if anyone can help me.
On the first render the value for types will be undefined ( on sync code execution ), try using it as
<select className={styles.input} title="type" name="type" onChange={e => setType(e.target.value)} value={types}>
{types?.map(type=>
<option key={type.id} value={type.id}>{type.type}</option>
)}
</select>
? will make sure to run map once value for types is there ( also make sure it is mappable ( is an array ))
Handle the array falsy cases before doing any operations on it
<select
className={styles.input}
title="type" name="type"
onChange={e => setType(e.target.value)}
value={types}
>
{types.length && types.map(type=>
<option key={type.id} value={type.id}>{type.type}</option>
)}
</select>
Related
I am trying to create a new object for ingredient quantity measure for each new ingredient the user creates. I can make the object for 1 of the ingredient-triad divs but I am stumped about how to create several objects with different ingredients added by user eg.
ingredientList = [
{
ingredient_name: flour,
ingredient_quantity: 1,
ingredient_measure: cup
},
{
ingredient_name: water,
ingredient_quantity: 1,
ingredient_measure: tbsp
}
]
etc.
Here is where I have gotten to:
export default function Recipe() {
const [name, setName] = useState('')
const [method, setMethod] = useState('')
const [ingredient, setIngredient] = useState('')
const [ingredientyQty, setIngredientQty] = useState('')
const [ingredientMeasure, setIngredientMeasure] = useState('')
const ingredientList = []
const recipeIngredient = {
ingredient_name: ingredient,
quantity: ingredientyQty,
measure: ingredientMeasure,
}
ingredientList.push(recipeIngredient)
const sendRecipeName = function (e) {
e.preventDefault()
fetch('http://localhost:3001/recipe', {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify({ name: name, method: method }),
})
.then((resp) => resp.json())
.then((json) => console.log(json))
}
return (
<div>
[...]
<div className="ingredient-triad">
<input
className="ingredient"
type="text"
onChange={(e) => setIngredient(e.target.value)}
></input>
<input
className="quantity"
type="text"
onChange={(e) => setIngredientQty(e.target.value)}
></input>
<select
className="dropdown"
name="measure"
id="measure"
onChange={(e) => setIngredientMeasure(e.target.value)}
>
<option value="cup">cup</option>
[...]
</select>
</div>
<div className="ingredient-triad">
<input
className="ingredient"
type="text"
onChange={(e) => setIngredient(e.target.value)}
></input>
<input
className="quantity"
type="text"
onChange={(e) => setIngredientQty(e.target.value)}
></input>
<select
className="dropdown"
name="measure"
id="measure"
onChange={(e) => setIngredientMeasure(e.target.value)}
>
<option value="cup">cup</option>
[...]
</select>
</div>
<div className="save-button-container">
<button className="save-recipe" onClick={(e) => sendRecipeName(e)}>
Submit Recipe
</button>
</div>
</form>
</div>
</div>
)
}
import React, { useState } from "react";
const init = {
ingredient_name: "",
quantity: "",
measure: ""
};
export default function App() {
const [ingredientList, setIngredientList] = useState([
{
ingredient_name: "",
quantity: "",
measure: ""
}
]);
const handleChange = (e, i) => {
const { name, value } = e.target;
setIngredientList((prevState) => {
const newIngredientList = [...prevState];
newIngredientList[i][name] = value;
return [...newIngredientList];
});
};
return (
<>
[...]
{ingredientList.map((list, i) => (
<div key={i} className="ingredient-triad">
<input
className="ingredient"
name="ingredient_name"
type="text"
value={list.ingredient_name}
onChange={(e) => handleChange(e, i)}
></input>
<input
className="quantity"
name="quantity"
type="text"
value={list.quantity}
onChange={(e) => handleChange(e, i)}
></input>
<select
className="dropdown"
name="measure"
id="measure"
value={list.measure}
onChange={(e) => handleChange(e, i)}
>
<option value="" disabled>
--none--
</option>
<option value="cup">cup</option>
</select>
<button onClick={() => setIngredientList((prev) => [...prev, init])}>
+
</button>
</div>
))}
[...]
</>
);
}
I think this is what you are looking for :)
Try this below code:
export default function Recipe() {
const [name, setName] = useState('')
const [method, setMethod] = useState('')
const [ingredientList, setIngredientList] = useState([])
const [ingredient, setIngredient] = useState('')
const [ingredientyQty, setIngredientQty] = useState('')
const [ingredientMeasure, setIngredientMeasure] = useState('')
console.log(ingredientList)
const sendRecipeName = function (e) {
e.preventDefault()
const recipeIngredient = {
ingredient_name: ingredient,
quantity: ingredientyQty,
measure: ingredientMeasure,
}
setIngredientList((prev) => [...prev, recipeIngredient])
fetch('http://localhost:3001/recipe', {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify({ name: name, method: method }),
})
.then((resp) => resp.json())
.then((json) => console.log(json))
}
return (
<div>
[...]
<div className="ingredient-triad">
<input
className="ingredient"
type="text"
onChange={(e) => setIngredient(e.target.value)}
></input>
<input
className="quantity"
type="text"
onChange={(e) => setIngredientQty(e.target.value)}
></input>
<select
className="dropdown"
name="measure"
id="measure"
onChange={(e) => setIngredientMeasure(e.target.value)}
>
<option value="cup">cup</option>
[...]
</select>
</div>
<div className="ingredient-triad">
<input
className="ingredient"
type="text"
onChange={(e) => setIngredient(e.target.value)}
></input>
<input
className="quantity"
type="text"
onChange={(e) => setIngredientQty(e.target.value)}
></input>
<select
className="dropdown"
name="measure"
id="measure"
onChange={(e) => setIngredientMeasure(e.target.value)}
>
<option value="cup">cup</option>
[...]
</select>
</div>
<div className="save-button-container">
<button className="save-recipe" onClick={(e) => sendRecipeName(e)}>
Submit Recipe
</button>
</div>
</form>
</div>
</div>
)
}
I have a react app with edit logic with select tag and options for continents and countries. In the continents it seems everything is alright but in countries I can't set a first option. First I must to select another country and then first option is available for set.
This is my code:
import React, { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './editContact.module.css';
import { urls, methods } from '../constants';
import requester from '../services/requester';
import notificationsReceiver from '../services/notificationReceiver';
const EditContact = () => {
const id = window.location.pathname.slice(14);
const navigate = useNavigate();
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [description, setDescription] = useState('');
const [categories, setCategories] = useState('');
const [areas, setAreas] = useState('');
const [event, setEvent] = useState('');
const [continentId, setContinent] = useState('');
const [countryId, setCountry] = useState('');
const [continents, setContinents] = useState([]);
const [countries, setCountries] = useState([]);
const getContact = useCallback(async () => {
const request = await requester(urls.contacts + '/' + id, methods.get);
const response = await request.json();
setName(response.name);
setEmail(response.email);
setAreas(response.areas);
setCategories(response.categories);
setDescription(response.description);
setEvent(response.event);
setPhone(response.phoneNumber);
setContinent(response.continentId);
setCountry(response.countryId);
}, [id]);
const sendToHome = () => {
navigate(urls.mainPage);
};
const editContact = async (e) => {
e.preventDefault();
await requester(urls.contacts + '/' + id, methods.put, {
name,
email,
phone,
description,
areas,
event,
categories,
continentId,
countryId
}
)
.then(() => {
navigate(urls.mainPage);
notificationsReceiver('Contact is edited successfully!');
})
.catch((e) => {
alert(e.message);
})
};
const getContinents = async () => {
const request = await requester(urls.getContinents, methods.get);
const response = await request.json();
setContinents(response);
};
const getCountries = async () => {
const request = await requester(urls.getCountries, methods.get);
const response = await request.json();
setCountries(response);
};
useEffect(() => {
getContact();
getContinents();
getCountries();
}, [getContact]);
return (
<form className={styles['edit-form']} onSubmit={editContact}>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Name</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setName(e.target.value)} value={name} />
</div>
<label htmlFor="exampleFormControlInput1">Continent</label>
<select className="form-control" id="exampleFormControlSelect1" title="continent" name="continent" onChange={e => setContinent(e.target.value)} value={continentId}>
{continents.map(continent =>
<option key={continent.continentId} value={continent.continentId}>{continent.continentName}</option>
)}
</select>
<label htmlFor="exampleFormControlInput1">Countries</label>
<select className="form-control" id="exampleFormControlSelect1" title="country" name="country" onChange={e => setCountry(e.target.value)} value={countryId}>
{countries.filter(x => x.placeIsContainedInId === continentId).map(country =>
<option key={country.countryId} value={country.countryId}>{country.countryName}</option>
)}
</select>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">eMail</label>
<input type="email" className="form-control" id="exampleFormControlInput1" onChange={e => setEmail(e.target.value)} value={email} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Phone</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setPhone(e.target.value)} value={phone} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Description</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setDescription(e.target.value)} value={description} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Categories</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setCategories(e.target.value)} value={categories} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Areas</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setAreas(e.target.value)} value={areas} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Event</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setEvent(e.target.value)} value={event} />
</div>
<button type='submit' className='btn btn-success mt-5' style={{ marginRight: 5 + 'px' }} name='edit'>Submit</button>
<button className='btn btn-secondary mt-5' onClick={sendToHome}>Cancel</button>
</form>
);
};
export default EditContact;
If someone knows how to resolve this problem, I'll be grateful.
I have a React app in front-end with ASP.NET Web Api in back-end. When I try to make a PUT request from React to Web Api in the console appears error with number 400. With all other requests everything is fine. I put a breakpoint in ASP.NET in debug but even then request doesn't get in Web API.
This is my code in React:
import React, { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './editContact.module.css';
const EditContact = () => {
const id = window.location.pathname.slice(14);
const navigate = useNavigate();
const [contactName, setContactName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [description, setDescription] = useState('');
const [categories, setCategories] = useState('');
const [areas, setAreas] = useState('');
const [event, setEvent] = useState('');
const [continent, setContinent] = useState('');
const [country, setCountry] = useState('');
const getContact = useCallback (async () => {
const request = await fetch(`https://localhost:7082/api/contacts/${id}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const response = await request.json();
setContactName(response.name);
setEmail(response.email);
setAreas(response.areas);
setCategories(response.categories);
setDescription(response.description);
setEvent(response.event);
setPhone(response.phoneNumber);
setContinent(response.continent);
setCountry(response.country);
}, [id]);
const sendToHome = () => {
navigate('/');
};
const editContact = async (e) => {
e.preventDefault();
await fetch(`https://localhost:7082/api/contacts/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
contactName,
email,
phone,
description,
areas,
event,
categories,
continent,
country
})
})
.then(() => {
navigate('/');
})
.catch((e) => {
alert(e.message);
})
};
useEffect(() => {
getContact();
}, [getContact]);
return (
<form className={styles.form} onSubmit={editContact}>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Name</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setContactName(e.target.value)} value={contactName} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">eMail</label>
<input type="email" className="form-control" id="exampleFormControlInput1" onChange={e => setEmail(e.target.value)} value={email} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Phone</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setPhone(e.target.value)} value={phone} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Description</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setDescription(e.target.value)} value={description} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Categories</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setCategories(e.target.value)} value={categories} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Areas</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setAreas(e.target.value)} value={areas} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Event</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setEvent(e.target.value)} value={event} />
</div>
<button type='submit' className='btn btn-success mt-5' style={{ marginRight: 5 + 'px' }} name='edit'>Submit</button>
<button className='btn btn-secondary mt-5' onClick={sendToHome}>Cancel</button>
</form>
);
};
export default EditContact;
And this is my code in ASP.NET:
[Route("api/[controller]")]
[ApiController]
public class ContactsController : ControllerBase
{
private readonly IContactsService contactsService;
public ContactsController(IContactsService contactsService)
{
this.contactsService = contactsService;
}
[HttpGet]
public JsonResult AllContacts()
{
var result = this.contactsService.GetAllContacts();
return new JsonResult(result);
}
[HttpGet("{id}")]
public JsonResult ContactDetails(string id)
{
var result = this.contactsService.GetContactDetails(id);
return new JsonResult(result);
}
[HttpPost]
public ActionResult AddContact(AddContactViewModel model)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest();
}
this.contactsService.AddContact(model);
return this.Ok();
}
[HttpPut("{id}")]
public ActionResult EditContact(string id, EditContactViewModel model)
{
this.contactsService.EditContact(id, model);
return this.Ok();
}
}
I will happy if someone could help me.
I'm sure I'm missing something but I can't seem to figure out what it is. I'm trying to POST the dropdown menu but it doesn't show up in the console and I get a post 400 when I submit. Any help would be greatly appreciated. thank you <3
Sorry it's a lot of code but I'm still navigating through react and just need some help on this.
Also I have React, useState, and useEffect imported from "react" it's just not showing up on the code
import axios from "axios";
function PostForm() {
const url = "https://frontend-take-home.fetchrewards.com/form";
const [data, setData] = useState({
name: "",
email: "",
password: "",
occupations: "",
states: "",
});
const URL = "https://frontend-take-home.fetchrewards.com/form";
const [occupations, setOccupation] = useState([]);
const [states, setState] = useState([]);
useEffect(function () {
axios
.get(URL)
.then((data) => setOccupation(data.data.occupations))
.catch((error) => console.log(error));
axios
.get(URL)
.then((data) => setState(data.data.states))
.catch((error) => console.log(error));
}, []);
function handle(e) {
const newData = { ...data };
newData[e.target.id] = e.target.value;
setData(newData);
console.log(newData);
}
function submit(e) {
e.preventDefault();
axios.post(url, data).then((res) => {
console.log(res.data);
});
}
return (
<div>
<form onSubmit={(e) => submit(e)}>
<label>Full Name</label>
<input
onChange={(e) => handle(e)}
id="name"
value={data.name}
placeholder="Full Name"
type="text"
name="name"
/>
<label>Email</label>
<input
onChange={(e) => handle(e)}
id="email"
value={data.email}
placeholder="Email"
type="text"
name="email"
/>
<label>Password</label>
<input
onChange={(e) => handle(e)}
id="password"
value={data.password}
placeholder="Password"
type="password"
name="password"
/>
<div>
<select>
{occupations.map((occupation) => (
<option
key={occupation}
id="occupation"
name="occupations"
placeholder="Occupation"
onChange={(e) => handle(e)}
value={data.occupations}
>
{occupation}
</option>
))}
</select>
<select>
{states.map((state) => (
<option
key={state.id}
value={data.states}
onChange={(e) => handle(e)}
>
{state.name}({state.abbreviation})
</option>
))}
</select>
</div>
<button type="submit">Sign Up</button>
</form>
</div>
);
}
export default PostForm;
It could be your server error which you are trying to request which means your code is correct , try to provide the full error message for more specific answer
I'm trying to post multiple variables to my Postgres database using a form with React.
This is my current script:
const InputAddress = () => {
const [name, setName] = useState("");
const [problem, setProblem] = useState("");
const [date, setDate] = useState("");
const onSubmitForm = async (e) => {
e.preventDefault();
try {
const body = {
name,
problem,
date,
};
console.log(params);
const response = await fetch("http://localhost:5000/logements", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
console.log(response);
window.location = "/";
} catch (error) {
console.log(error.message);
}
};
return (
<Fragment>
<h1 className="text-center mt-5">Add your address</h1>
<form className="d-flex mt-5" onSubmit={onSubmitForm}>
<label>Name</label>
<input
type="text"
className="form-control"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<label>Comment</label>
<input
type="text"
className="form-control"
value={problem}
onChange={(e) => setProblem(e.target.value)}
/>
<label>Date</label>
<input
type="text"
className="form-control"
value={date}
onChange={(e) => setDate(e.target.value)}
/>
<button className="btn btn-success">Submit</button>
</form>
</Fragment>
);
};
My problem seems to be with the fetch method.
When I submit the form, I get this error message in the console :
bind message supplies 1 parameters, but prepared statement "" requires 3
Is there a simple fix to this problem?