can't edit data in Textfield in reactjs - reactjs

I'm trying to edit the api data on a Mui datagrid. I want a modal form to pop on clicking the edit icon. Everything works fine, I'm getting the data to be edited and all that. thing is the data I'm getting in textfield for edit, is not changing the value. it's not taking any inputs I'm giving, it stays the same. what should I do to make the textfields editable ? Thanks in advance.
export default function ContactsCard(props) {
const [ContactData, setContactData] = useState([]);
const [open, setOpen] = useState(false);
const [formInputData, setformInputData] = useState(
{
name: '',
details: '',
}
);
const handleChange = (evnt) => {
const newInput = (data) => ({
...data,
[evnt.target.name]: evnt.target.value
});
setformInputData(newInput);
}
const showData = () => {
axios.get('http://localhost:8006/api/v2/get/beneficiaries-list').then(function (res) {
try {
var result = res.data;
// console.log(result.data)
setContactData(result.data)
}
catch (error) {
console.log(error)
}
})
}
const handleSubmit = (evnt) => {
evnt.preventDefault();
const formData = new FormData(); //formdata object
formData.append('nickname', formInputData.name); //append the values with key, value pair
formData.append('target', formInputData.details);
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
axios.post('http://localhost:8006/api/v2/save/beneficiary', formData, config)
.then(response => {
if (response.data.success === true) {
showData()
alert(response.data.message)
}
})
.catch(error => {
alert(error.message);
});
setformInputData({ name: "", details: "" });
setOpen(false);
}
const handleEdit = (id) => {
var edit_id = id.row.id
console.log(edit_id)
setOpen(true)
setformInputData(ContactData.find((data) => data.id === edit_id))
setOpen(true)
}
const handleOpen = () => setOpen(true)
const handleClose = () => setOpen(false);
useEffect(() => {
showData();
}, [])
const handleDelete = (id) => {
var del_id = id.row.id
console.log(del_id)
axios.post('http://localhost:8006/api/v2/remove/beneficiary/', { id: del_id }).then(res => {
console.log(res.data)
if (res.data.success === true) {
alert(res.data.message)
showData();
console.log('ajh');
}
})
};
const columns = [
{ field: 'name', headerName: 'Nick Name', width: '130' },
{ field: 'details', headerName: 'Deposit address', width: '130' },
{
field: 'actions',
type: 'actions',
width: '130',
headerName: 'Actions',
cellClassName: 'actions',
renderCell: (id) => {
return (
<>
<IconButton color="primary" onClick={(e) => { handleEdit(id) }}>
<EditIcon />
</IconButton>
<IconButton color="error" onClick={(e) => {
handleDelete(id)
}}>
<DeleteIcon />
</IconButton>
</>
);
},
},
];
return (
<Card {...props}>
<CardContent>
<ContactDataGrid rows={ContactData} columns={columns} />
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<FormControl sx={style} mt={1} >
<Typography sx={{ fontSize: 16, fontWeight: 'bold' }} color="text.secondary" gutterBottom>
Edit Contact
</Typography>
<Stack flexDirection='column' gap={1.5} mt={1}>
<TextField autoFocus required
id="filled-hidden-label-small"
label="Nick Name" variant="outlined" size="small"
onChange={handleChange}
value={formInputData.name}
name="Nick Name"
className="form-control"
/>
<TextField required
id="filled-hidden-label-small"
label="Deposit Address" variant="outlined" size="small"
onChange={handleChange}
value={formInputData.details}
name="Amount"
className="form-control"
/>
</Stack>
<Stack flexDirection='row' justifyContent={'center'} gap={1.5} mt={1}>
<Button
variant="contained"
type="submit" color="error"
onClick={handleClose}
sx={{ alignSelf: 'center' }} >Cancel</Button>
<Button
variant="contained"
type="submit"
onClick={handleSubmit}
sx={{ alignSelf: 'center', backgroundColor: '#000073' }} >Submit</Button>
</Stack>
</FormControl>
</Fade>
</Modal>
</CardContent>
</Card>
);
}

Your handleChange function is updating the new value in event.target.name but, the name doesn't match with the value. You can try changing the name to match the value getter:
<TextField autoFocus required
id="filled-hidden-label-small"
label="Nick Name" variant="outlined" size="small"
onChange={handleChange}
value={formInputData.name}
name="name" // this changed
className="form-control"
/>
<TextField required
id="filled-hidden-label-small"
label="Deposit Address" variant="outlined" size="small"
onChange={handleChange}
value={formInputData.details}
name="details" // this changed
className="form-control"
/>

Related

Not able to set values on Material UI TextField Select component

I am new to React.
I want to build a Form that has a Text field and a dropdown with 2 selections.
The form renders but I am unable to select any values from the dropdown. The handleChange function doesnt run.
const Category = () => {
const theme = useTheme();
const colors = tokens(theme.palette.mode);
const [formValues, setformValues] = useState({
categoryName: "Test",
categoryType: "Expense",
})
const categories = [
{
value: 'Income',
label: 'Income',
},
{
value: 'Expense',
label: 'Expense',
},
];
const handleFormSubmit = (values) => {
console.log(`Submitting : ${JSON.stringify(values)}`);
};
const isNonMobile = useMediaQuery("(min-width:600px)");
const handleCategoryTextChange = (event) => {
console.log(`Category Text Change ${event}`);
setformValues({
...formValues,
categoryName: event.target.value,
})
}
const handleCategoryChange = (event) => {
console.log(`Category Change Event ${event.target.value}`);
setformValues({
...formValues,
categoryType: event.target.value
})
};
return (
<Box>
<Box m="20px">
<Header title="CREATE CATEGORY" subtitle="Create a New Category" />
<form onSubmit={handleFormSubmit}>
<Box
display="grid"
gap="30px"
gridTemplateColumns="repeat(4, minmax(0, 1fr))"
sx={{
"& > div": { gridColumn: isNonMobile ? undefined : "span 4" },
}}
>
<TextField
fullWidth
variant="filled"
type="text"
label="Category Name"
onChange={handleCategoryTextChange}
value={formValues.categoryName}
name="categoryName"
sx={{ gridColumn: "span 2" }}
/>
<TextField
fullWidth
variant="filled"
label="Category Type"
onChange={handleCategoryChange}
value={formValues.categoryType}
name="categoryType"
sx={{ gridColumn: "span 2" }}
select
>
{categories.map((option) => (
<MenuItem key = {option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Box>
</form>
</Box>
</Box>
);
};
I am expecting the dropdown to be selectable and the handleChange events to be triggered.
Once this is working, I would submit the form values to an API endpoint

React and Antd, form data destroys on fulllscreen drawer out of focus

I have tried to remove the destroy on close, use same form hook, different form hook, removed from hook, but nothing worked.
I have consoled logged the form data on show modal and close modal. Show modal has the form data but inside the log of close modal the data is reset to undefined. As soon as the modal opens the Data resets to null.
In the following code you can see the creation of Full screen modal which is made using AntDrawer:
import React, { useEffect, useState } from "react";
import FullscreenDialog from "Components/FullScreenDialog";
import Form from "Components/Form";
import { Input, Typography, Button, Space, Menu, Dropdown } from "antd";
import { PlusCircleOutlined, CloseOutlined, DownOutlined } from "#ant-design/icons";
import HeaderInput from "Components/Inputs/HeaderInput";
import Table from "Components/Table";
import styled from "styled-components";
import { Services } from "Utilities/network";
import DetailsModal from "./DetailsModal";
const RootWrapper = styled.div`
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
`;
const CreateVoucher = ({ visible, initalValue = {}, onSuccess = (e) => e, onClose = (e) => e }) => {
const [form] = Form.useForm();
const [voucherData, setVoucherData] = useState([]);
const [newModal, setNewModal] = useState(false);
const [formData, setFormData] = useState({});
const handleSubmit = async () => {
const { _id, name, header } = form.getFieldsValue(true);
if (name && header && voucherData) {
let resp = await Services.createVoucher({
_id,
name,
header,
voucherData,
});
if (resp.key) onSuccess();
}
};
if (initalValue) {
const { _id, name, header, voucherData } = initalValue;
form.setFieldsValue({
_id,
name,
header,
voucherData,
});
}
useEffect(() => {
const { voucherData } = initalValue;
if (voucherData && voucherData.length) setVoucherData(voucherData);
else setVoucherData([]);
}, [initalValue]);
const handleDelete = (index) => {
const tableData = voucherData.filter((data, dataIndex) => {
if (index !== dataIndex) return data;
return null;
});
setVoucherData(tableData);
};
return (
<>
<FullscreenDialog visible={visible} onClose={onClose}>
<FullscreenDialog.Paper>
<RootWrapper>
<Typography.Text strong style={{ fontSize: "30px" }}>
Generate Voucher
</Typography.Text>
<Form form={form}>
<Space direction="vertical" style={{ width: "100%" }}>
<Form.Item label="Voucher ID" name="name" rules={[{ required: true, message: "Please input ID" }]}>
<Input />
</Form.Item>
<HeaderInput
fieldProps={{
name: "header",
label: "Inoivce Header",
rules: [{ required: true, message: "Please select header" }],
}}
itemProps={{ placeholder: "Select Header for Voucher" }}
/>
<Space style={{ float: "right", marginTop: "20px" }}>
<Button
type="primary"
shape="round"
icon={<PlusCircleOutlined />}
onClick={() => {
setFormData(form.getFieldsValue(true));
setNewModal(true);
}}
>
Add Details
</Button>
</Space>
<Table
dataSource={voucherData}
count={voucherData?.length || 0}
columns={[
{
title: "Label",
key: "label",
dataIndex: "label",
render: (_, record) => record.label,
},
{
title: "Details",
key: "detail",
dataIndex: "detail",
render: (_, record) => record.detail,
},
{
align: "right",
render: (_, record, index) => {
return (
<Dropdown
trigger={["click"]}
overlay={
<Menu>
<Menu.Item
style={{ color: "red " }}
onClick={() => {
handleDelete(index);
}}
>
<CloseOutlined /> Delete
</Menu.Item>
</Menu>
}
>
<Button type="primary">
Edit
<DownOutlined />
</Button>
</Dropdown>
);
},
},
]}
/>
<Space style={{ float: "right", marginTop: "30px" }}>
<Button type="outline" onClick={onClose}>
Cancel
</Button>
<Button type="primary" htmlType="submit" onClick={handleSubmit}>
Submit
</Button>
</Space>
</Space>
</Form>
</RootWrapper>
</FullscreenDialog.Paper>
</FullscreenDialog>
<DetailsModal
visible={newModal}
onClose={() => {
setNewModal(false);
console.log(formData);
form.setFieldsValue({ name: "2222" });
console.log(form.getFieldsValue(true));
}}
onSuccess={(data) => {
setVoucherData([...voucherData, data]);
setNewModal(false);
form.setFieldsValue(formData);
}}
/>
</>
);
};
export default CreateVoucher;
Below is the code for modal to use another form:
import React from "react";
import { Modal, Space, Input, Button } from "antd";
import Form from "Components/Form";
import styled from "styled-components";
const RootWrapper = styled.div`
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
`;
const DetailsModal = ({ visible, onClose = (e) => e, onSuccess = (e) => e }) => {
const [form] = Form.useForm();
return (
<Modal
visible={visible}
destroyOnClose={true}
onClose={() => {
form.resetFields();
onClose();
}}
onCancel={() => {
form.resetFields();
onClose(false);
}}
title="Add Details"
footer={false}
>
<Form form={form}>
<Space direction="vertical" style={{ width: "100%" }}>
<RootWrapper>
<Form.Item name="label" label="Label" rules={[{ required: true, message: "Please input label" }]}>
<Input />
</Form.Item>
<Form.Item name="detail" label="Details" rules={[{ required: true, message: "Please input details" }]}>
<Input />
</Form.Item>
</RootWrapper>
<Space style={{ float: "right", marginTop: "20px" }}>
<Button
type="outline"
onClick={() => {
form.resetFields();
onClose();
}}
>
Cancel
</Button>
<Button
type="primary"
htmlType="submit"
onClick={() => {
const { detail, label } = form.getFieldsValue(true);
onSuccess({ detail, label });
}}
>
Submit
</Button>
</Space>
</Space>
</Form>
</Modal>
);
};
export default DetailsModal;

Material UI Avatar Image Upload

I managed it to make an Avatar chooser, but I don't know how to save the picture in Firebase or how to even save it as a Profile picture.
This is how it looks like:
This comes out if I click on the button:
I can choose a pic, but it just not saving it anywhere and also not displaying the picture in the avatar.
My code:
function Profile(props, navigation) {
const classes = useStyles();
const user = useUser(props.route.params.uid);
const [time, setTime] = useState("7:30");
const [timing, setTiming] = useState([]);
const [timeAfternoon, setTimeAfternoon] = useState("7:30");
const [timingAfternoon, setTimingAfternoon] = useState([]);
const [sickDaysStart, setSickDaysStart] = useState(Date.now());
const [sickDaysEnd, setSickDaysEnd] = useState(Date.now());
const [sickDaysConfirm, setSickDaysConfirm] = useState([]);
const [donwloadURL, setDownloadURL] = useState([]);
const onLogout = () => {
firebase.auth().signOut();
};
function handelSickDaysStart(e) {
setSickDaysStart(e.target.value);
}
function handelSickDaysEnd(e) {
setSickDaysEnd(e.target.value);
}
function handleTime(e) {
setTime(e.target.value);
}
function handleTimeAfternoon(e) {
setTimeAfternoon(e.target.value);
}
function delayMorning() {
db.collection("delayInTheMorning")
.doc()
.set({
time,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTiming([...timing, { time }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function delayAfternoon() {
db.collection("delayInTheAfternoon")
.doc()
.set({
timeAfternoon,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTimingAfternoon([...timingAfternoon, { timeAfternoon }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function sickDaysStartEnd() {
db.collection("DaysofSickness")
.doc()
.set({
sickDaysStart,
sickDaysEnd,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setSickDaysConfirm([
...sickDaysConfirm,
{ sickDaysStart, sickDaysEnd },
]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function isCurrentUserProfile() {
if (props.route.params.uid === firebase.auth().currentUser.uid) {
return true;
} else {
return false;
}
}
async function handleFileInputChange(e) {
const files = e.target.files;
const file = files[0];
const storage = firebase.storage();
const usersImageRef = storage
.ref()
.child(`users/${user.uid}/profilepicture.jpg`);
const snap = await usersImageRef.put(file);
const donwloadURL = await snap.ref.getDownloadURL();
setDownloadURL(donwloadURL);
await firebase.auth().currentUser.updateProfile({ photoURL: donwloadURL });
}
if (user === null) {
return <div className={classes.root} />;
}
return (
<ScrollView style={styles.root}>
<Container className={classes.div}>
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
onChange={handleFileInputChange}
/>
<label>
<IconButton>
<Avatar
src="../assets/ana.png"
style={{
margin: "10px",
width: "60px",
height: "60px",
}}
/>
</IconButton>
</label>
<Typography className={classes.text}> {user.name} </Typography>
<Typography className={classes.text}> {user.email} </Typography>
{isCurrentUserProfile() ? (
<Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onLogout()}
>
Logout
</Button>
) : null}
</Container>
<Card className={classes.div}>
{/* //Verspätung */}
<CardContent className={classes.cardBackGround}>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Verspätung{" "}
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={(value) => {
handleTime(value);
}}
/>
<Button className={classes.cardBtn} onClick={() => delayMorning()}>
Absenden
</Button>
</Container>
</CardContent>
{/* //Krankenmledungen */}
<CardContent className={classes.cardBackGround}>
<Typography variant="h5" className={classes.cardTyp}>
Krankenmledungen
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="date"
label="Von"
type="date"
defaultValue="2021-09-14"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysStart(value);
}}
/>
<TextField
id="date"
label="bis"
type="date"
defaultValue="2021-09-20"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysEnd(value);
}}
/>
</Container>
<Button
className={classes.cardBtnKM}
onClick={() => sickDaysStartEnd()}
>
Absenden
</Button>
</CardContent>
{/* //Verspätung Abolung*/}
<CardContent className={classes.cardBackGround}>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Verspätung Abholung
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={(value) => {
handleTimeAfternoon(value);
}}
/>
<Button
className={classes.cardBtn}
onClick={() => delayAfternoon()}
>
Absenden
</Button>
</Container>
</CardContent>
</Card>
{/* <List> */}
{/* Verspätungs Liste */}
{timing.map((item) => {
return (
<List className={classes.lists}>
<ListItem className={classes.list1}>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung in der Früh ${item.time}`}
/>
</ListItem>
</List>
);
})}
{/* Krankmeldung */}
{timingAfternoon.map((item) => {
return (
<List className={classes.lists}>
<ListItem className={classes.list}>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung bei der Abholung ${item.timeAfternoon}`}
/>
</ListItem>
</List>
);
})}
{/* Verspätungs Nachmittag */}
{sickDaysConfirm.map((item) => {
return (
<List className={classes.lists}>
<ListItem className={classes.list}>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Krankmeldung von ${item.sickDaysStart} bis ${item.sickDaysEnd}`}
/>
</ListItem>
</List>
);
})}
</ScrollView>
);
}
There is also a imagePicker from Expo, I was thinking of trying that but I'm just not sure.
If you want to change the profile picture of a user you can use this code:
import { getAuth, updateProfile } from "firebase/auth";
const auth = getAuth();
updateProfile(auth.currentUser, {
displayName: "User Name", photoURL: "https://example.com/jane-q-user/profile.jpg"
}).then(() => {
// Profile updated!
// ...
}).catch((error) => {
// An error occurred
// ...
});
You can find more info about it here.
To get the picture URL you would need to upload it to Firebase Storage and get the downloadURL:
import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";
const storage = getStorage();
const storageRef = ref(storage, 'some-child');
// 'file' comes from the Blob or File API
uploadBytes(storageRef, file).then((snapshot) => {
console.log('Uploaded a blob or file!');
getDownloadURL(snapshot.ref).then((downloadURL) => {
console.log('File available at', downloadURL);
});
});
I would also change the input to not have multiple files to select. If you would share more of your code I can integrate those code snippets in your code in case you have problems with it.
UPDATE:
Here is the whole example. I see you use the old SDK so the example is with it:
function Profile(props, navigation) {
const classes = useStyles();
const user = useUser(props.route.params.uid);
const delay = DayandTime();
const [time, setTime] = useState("7:30");
const [timing, setTiming] = useState([]);
const [downloadurl, setDU] = useState("/images/example.jpg");
const [timeAfternoon, setTimeAfternoon] = useState("7:30");
const [timingAfternoon, setTimingAfternoon] = useState([]);
const [sickDaysStart, setSickDaysStart] = useState(Date.now());
const [sickDaysEnd, setSickDaysEnd] = useState(Date.now());
const [sickDaysConfirm, setSickDaysConfirm] = useState([]);
const onLogout = () => {
firebase.auth().signOut();
};
function handelSickDaysStart(e) {
setSickDaysStart(e.target.value);
}
function handelSickDaysEnd(e) {
setSickDaysEnd(e.target.value);
}
function handleTime(e) {
setTime(e.target.value);
}
function handleTimeAfternoon(e) {
setTimeAfternoon(e.target.value);
}
function delayMorning() {
db.collection("delayInTheMorning")
.doc()
.set({
time,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTiming([...timing, { time }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function delayAfternoon() {
db.collection("delayInTheAfternoon")
.doc()
.set({
timeAfternoon,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTimingAfternoon([...timingAfternoon, { timeAfternoon }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function sickDaysStartEnd() {
db.collection("DaysofSickness")
.doc()
.set({
sickDaysStart,
sickDaysEnd,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setSickDaysConfirm([
...sickDaysConfirm,
{ sickDaysStart, sickDaysEnd },
]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function isCurrentUserProfile() {
if (props.route.params.uid === firebase.auth().currentUser.uid) {
return true;
} else {
return false;
}
}
if (user === null) {
return <div className={classes.root} />;
}
async function handleFileInputChange(e) {
const files = e.target.files;
const file = files[0];
const storage = firebase.storage();
const usersImageRef = storage
.ref()
.child(`users/${user.uid}/profilepicture.jpg`);
const snap = await usersImageRef.put(file);
const downloadURL = await snap.ref.getDownloadURL();
setDU(downloadURL);
await firebase.auth().updateProfile({ photoURL: downloadURL });
}
return (
<ScrollView style={styles.root}>
<Container className={classes.div}>
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
onChange={handleFileInputChange}
/>
<label htmlFor="contained-button-file">
<IconButton>
<Avatar
src="/images/example.jpg"
style={{
margin: "10px",
width: "60px",
height: "60px",
}}
/>
</IconButton>
</label>
<Typography className={classes.text}> {user.name} </Typography>
<Typography className={classes.text}> {user.email} </Typography>
{isCurrentUserProfile() ? (
<Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onLogout()}
>
Logout
</Button>
) : null}
</Container>
<Card className={classes.div}>
{/* //Verspätung */}
<CardContent>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Verspätung{" "}
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={(value) => {
handleTime(value);
}}
/>
<Button className={classes.cardBtn} onClick={() => delayMorning()}>
Absenden
</Button>
</Container>
</CardContent>
{/* //Krankenmledungen */}
<CardContent className={classes.cardKrankmeldung}>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Krankenmledungen{" "}
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="date"
label="Von"
type="date"
defaultValue="2021-09-14"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysStart(value);
}}
/>
<TextField
id="date"
label="bis"
type="date"
defaultValue="2021-09-20"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysEnd(value);
}}
/>
</Container>
<Button
className={classes.cardBtnKM}
onClick={() => sickDaysStartEnd()}
>
Absenden
</Button>
</CardContent>
{/* //Verspätung Abolung*/}
<CardContent>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Verspätung Abholung
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={(value) => {
handleTimeAfternoon(value);
}}
/>
<Button
className={classes.cardBtn}
onClick={() => delayAfternoon()}
>
Absenden
</Button>
</Container>
</CardContent>
</Card>
<List>
{/* Verspätungs Liste */}
<ListItem>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung in der Früh ${delay}`}
/>
</ListItem>
{/* Verspätungs Krankmeldung */}
<ListItem>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Krankmeldung ${delay}`}
/>
</ListItem>
{/* Verspätungs Nachmittag */}
<ListItem>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung Nachmittag ${delay}`}
/>
</ListItem>
</List>
</ScrollView>
);
}
const mapStateToProps = (store) => ({
currentUser: store.userState.currentUser,
posts: store.userState.posts,
following: store.userState.following,
});
export default connect(mapStateToProps, null)(Profile);
const useStyles = makeStyles({
root: {
backgroundColor: "white",
},
div: {
marginTop: 20,
marginLeft: 15,
marginRight: 15,
backgroundColor: "white",
},
avatar: {
marginBottom: 10,
},
btn: {
marginTop: 10,
width: 250,
marginBottom: 30,
},
text: {
fontSize: 25,
marginTop: 10,
},
cardTyp: {
textAlign: "left",
paddingLeft: 13,
},
cardBtn: {
marginTop: 20,
marginLeft: 30,
},
cardBtnKM: {
marginTop: 20,
marginLeft: 10,
},
cardContainer: {
display: "flex",
},
});
const styles = StyleSheet.create({
root: {
backgroundColor: "white",
},
});

Trying to make a POST request to Firebase Firestore

import axios from 'axios'
import Copyright from '../components/Copyright'
// Material UI Stuff
import { makeStyles } from '#material-ui/core/styles'
import CircularProgress from '#material-ui/core/CircularProgress'
import Container from '#material-ui/core/Container'
import Typography from '#material-ui/core/Typography'
import TextField from '#material-ui/core/TextField'
import Button from '#material-ui/core/Button'
import Box from '#material-ui/core/Box'
const INITIAL_STATE = {
cohort: '',
program: '',
github: '',
website: '',
linkedIn: ''
}
const inputProps = {
step: 1,
min: 1,
max: 99
}
const Profile = () => {
const [formData, setFormData] = useState(INITIAL_STATE)
const [isloading, setIsLoading] = useState(false)
const [errors, setErrors] = useState({})
const [user, setUser] = useState(null)
const isInvalid = !formData.cohort || !formData.program || isloading
const handleInputChange = field => e => {
setFormData({ ...formData, [field]: e.target.value })
}
const fetchProfile = async () => {
const token = await localStorage.FBIdToken
await axios
.get(`/user`, {
headers: {
Authorization: `${token}`
}
})
.then(res => {
setUser(res.data)
setFormData({
...formData,
github: res.data.user.github ? res.data.user.github : '',
website: res.data.user.website ? res.data.user.website : '',
linkedIn: res.data.user.linkedIn ? res.data.user.linkedIn : '',
cohort: res.data.user.cohort,
program: res.data.user.program
})
})
.catch(err => console.log('*** WRONG ***'))
}
useEffect(() => {
fetchProfile()
}, [])
const handleSubmit = async e => {
e.preventDefault()
setIsLoading(true)
const fireToken = await localStorage.FBIdToken
await axios
.post(
(`/user`,
{
headers: {
Authorization: `${fireToken}`
}
})
)
.then(res => {
console.log(res.data)
setIsLoading(false)
})
.catch(err => {
console.log(err)
setIsLoading(false)
})
}
const useStyles = makeStyles(theme => ({
form: {
textAlign: 'center',
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
position: 'relative'
},
logo: {
width: 180,
height: 180,
display: 'block',
alignItems: 'center'
},
submit: {
margin: theme.spacing(3, 0, 2),
position: 'relative'
},
progress: {
position: 'absolute'
},
customError: {
color: 'red',
fontSize: '0.8rem',
width: '100%',
position: 'absolute'
}
}))
const classes = useStyles()
return (
<>
{user ? (
<div>
<Container component="main" maxWidth="xs">
<div className={classes.paper}>
<img
src={user.user.imageUrl}
alt="wyncode logo"
className={classes.logo}
/>
<Typography variant="h3" className={classes.pageTitle}>
Sign Up
</Typography>
<form noValidate onSubmit={handleSubmit} className={classes.form}>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="website"
type="website"
label="Website"
name="website"
autoComplete="website"
value={formData.website}
onChange={handleInputChange('website')}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="cohort"
type="number"
inputProps={inputProps}
label="Cohort #"
name="cohort"
autoComplete="cohort"
helperText={errors.cohort}
error={errors.cohort ? true : false}
value={formData.cohort}
onChange={handleInputChange('cohort')}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="linkedIn"
type="linkedIn"
label="LinkedIn"
name="linkedIn"
autoComplete="linkedIn"
value={formData.linkedIn}
onChange={handleInputChange('linkedIn')}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="github"
type="github"
label="GitHub"
name="github"
autoComplete="github"
value={formData.github}
onChange={handleInputChange('github')}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="program"
type="program"
label="Program"
name="program"
helperText={errors.program}
error={errors.program ? true : false}
autoComplete="program"
value={formData.program}
onChange={handleInputChange('program')}
/>
{errors.general && (
<Typography variant="body2" className={classes.customError}>
{errors.general}
</Typography>
)}
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
disabled={isInvalid}
>
Update User Info
{isloading && (
<CircularProgress size={30} className={classes.progress} />
)}
</Button>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
</div>
) : (
<CircularProgress size={60} className={classes.progressOne} />
)}
</>
)
}
export default Profile
I am fetching the token for my headers from local storage and trying to post the form data to my user endpoint. When I post, I get an error stating:
xhr.js:178 POST http://localhost:3000/[object%20Object] 404 (Not
Found)
I'm hitting the correct end point, but for some reason the post isn't hitting the /user endpoint with my form data. any insight would be awesome.

Material-ui Button onClick to submit a Dialog is not updating FormData. FormData.append is not appending

In this functionality, I am just uploading a file with some description field (containing some text) with the Dialog component of Material-UI and capturing the file and related description string with FormData() with the below handleUpload function that will be triggered on Button onClick.
handleUpload = event => {
event.preventDefault();
const data = new FormData();
data.append(
"file",
this.state.selectedFile,
this.state.document_name,
this.state.description
);
if (data.get("description") !== "" && data.get("document_name") !== "") {
this.props
.createGo(data, history)
.then(() => {
console.log("FORM DATA INSIDE", data);
console.log("FILE IS ", this.state.selectedFile);
this.setState({
open: true,
vertical: "top",
horizontal: "center"
});
})
.catch(error => {
if (error.response.status === 422) {
alert(
"File must be less than 10 MB and type must be one of pdf, jpeg, jpg, png, doc, xlx, xlsx, ppt pptx"
);
} else if (error.response.status === 401) {
history.push("/login");
alert("Please Login, session expired");
}
});
} else {
showEmptyFieldSnackbar();
return false;
}
};
When I am NOT using Material-UI Dialog then the its working as expected. The working code is here
But when I am using Material-UI to submit the dialog to uplaod the file, its not working because the FormData() remains empty. Note the line console.log("FORM DATA INSIDE", data); is giving me an empty FormData. That is, the following code
const data = new FormData();
data.append(
"file",
this.state.selectedFile,
this.state.document_name,
this.state.description
);
is NOT appending anything.
And here is my full component, using Material-UI to submit the dialog
class GoCreateForm extends Component {
constructor(props) {
super(props);
this.state = {
document_name: "",
description: "",
selectedFile: null,
open: false,
vertical: "top",
horizontal: "center",
dialogOpen: false
};
}
// and below handleClose function as well is for closing snackbar
handleClose = () => {
this.setState({ open: false });
history.push("/dashboard/gos");
};
handleSelectedFile = e => {
e.preventDefault();
this.setState({
selectedFile: e.target.files[0]
});
};
handleUpload = event => {
event.preventDefault();
const data = new FormData();
data.append(
"file",
this.state.selectedFile,
this.state.document_name,
this.state.description
);
if (data.get("description") !== "" && data.get("document_name") !== "") {
this.props
.createGo(data, history)
.then(() => {
console.log("FORM DATA INSIDE", data);
console.log("FILE IS ", this.state.selectedFile);
this.setState({
open: true,
vertical: "top",
horizontal: "center"
});
})
.catch(error => {
if (error.response.status === 422) {
alert(
"File must be less than 10 MB and type must be one of pdf, jpeg, jpg, png, doc, xlx, xlsx, ppt pptx"
);
} else if (error.response.status === 401) {
history.push("/login");
alert("Please Login, session expired");
}
});
} else {
showEmptyFieldSnackbar();
return false;
}
};
handleCancel = () => {
this.setState({
dialogOpen: false
});
};
handleEnterEscapeKeyPress = e => {
if (e.key === "Enter") {
this.onSubmit();
} else if (e.key === "Escape") {
this.handleCancel();
}
};
handleToggle = () => {
this.setState({
dialogOpen: !this.state.dialogOpen
});
};
handleFabOpen = () => {
this.setState({
dialogOpen: true
});
};
render() {
const {
vertical,
horizontal,
open,
document_name,
description,
selectedFile
} = this.state;
const { classes } = this.props;
return (
<MuiThemeProvider>
<FormControl>
<div>
<Fab
onClick={this.handleFabOpen}
aria-pressed="true"
color="secondary"
size="large"
aria-label="Add"
fontSize="large"
className={classes.fabButton}
>
<AddIcon />
</Fab>
<Dialog
open={this.state.dialogOpen}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
fullWidth={true}
maxWidth={"sm"}
variant="contained"
PaperProps={{
classes: {
root: classes.paper
}
}}
onKeyDown={this.handleEnterEscapeKeyPress}
>
<form onSubmit={this.handleUpload}>
<DialogTitle
id="form-dialog-title"
disableTypography
className={classes.dialogTitleAdd}
>
<div className={classes.displayFlexDialogTitle}>
<Typography
variant="h5"
className={classes.dialogTitleHeading}
>
Upload a new Government Order
</Typography>
<IconButton
onClick={this.handleToggle}
className={classes.button}
style={{ float: "right" }}
>
<CancelIcon />
</IconButton>
</div>
</DialogTitle>
<DialogContent required>
<div style={{ display: "flex", margin: "auto" }}>
<TextField
required
autoFocus
error={document_name === ""}
fullWidth
classes={{
root: classes.space
}}
type="string"
onChange={e => {
this.setState({
document_name: e.target.value
});
}}
value={document_name}
helperText={
document_name === ""
? "Please enter Document Name"
: " "
}
label="Document Name"
/>
</div>
<div style={{ display: "flex", margin: "auto" }}>
<TextField
required
autoFocus
multiline={true}
error={description === ""}
fullWidth
classes={{
root: classes.space
}}
type="string"
onChange={e => {
this.setState({
description: e.target.value
});
}}
value={description}
helperText={
description === ""
? "Please enter Document Description"
: " "
}
label="Document Description"
/>
</div>
{selectedFile === null ? null : (
<div style={{ marginBottom: "10px" }}>
{selectedFile.name}
</div>
)}
<div
style={{ display: "flex", margin: "auto" }}
className="form-group"
>
<Button variant="contained" component="label">
Upload File
<input
type="file"
style={{ display: "none" }}
onChange={this.handleSelectedFile}
/>
</Button>
</div>
</DialogContent>
<DialogActions className={classes.dialogActions}>
<div className={classes.displayFlexDialogActions}>
<Button
onClick={this.handleCancel}
variant="contained"
size="small"
color="secondary"
className="float-right"
style={{ marginRight: "10px" }}
>
<Link
style={{ textDecoration: "none", color: "inherit" }}
to="/dashboard/gos"
>
Cancel
</Link>
</Button>
<button type="submit" className="btn btn-primary">
Upload
</button>
</div>
</DialogActions>
</form>
</Dialog>
</div>
</FormControl>
</MuiThemeProvider>
);
}
}
GoCreateForm.propTypes = {
classes: PropTypes.object.isRequired
};
export default connect(
null,
{ createGo }
)(withStyles(styles)(GoCreateForm));

Resources