ReactJS .... map() is not a function - reactjs

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

Creating an array of objects from react events

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>
)
}

ReactJS select first option doesn't work properly

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.

ReactJS can't make request to ASP.NET Web API

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.

How to POST to server / I keep getting a post 400 error

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

Pass multiple variable with POST method in React app

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?

Resources