How to upload image in react - reactjs

I am working on a e-commerce app and there I am using form to add new product in app for that I am taking multiple inputs from user and then I am storing those inputs in my redux store and finally I am displaying newly added product in my app and everything is working perfectly here earlier I was using <input type="url"/> so user can paste an image url so I can display it and it was working perfectly but now I want to allow user so he can upload an Image from his local system instead or url using <input type="file"/> but this isn,t working this is not loading image from local system so is there any way I can upload Image from local system:
Form
import "./ProductForm.css";
import { useReducer } from "react";
import { useDispatch } from "react-redux";
import { addProductHandler } from "../../store/DataStore";
import { useNavigate } from "react-router-dom";
const ProductForm = () => {
const Dispatch = useDispatch();
const navigate = useNavigate();
const initialState = {
product_id: "",
product_name: "",
product_quantity: "",
product_description: "",
product_type: "",
product_valid: "false",
product_price: "",
product_title: "",
product_image: "",
};
const reducer = (state, action) => {
if (action.type === "id") {
return { ...state, product_id: action.value };
} else if (action.type === "name") {
return { ...state, product_name: action.value };
} else if (action.type === "title") {
return { ...state, product_title: action.value };
} else if (action.type === "price") {
return { ...state, product_price: action.value };
} else if (action.type === "image") {
return { ...state, product_image: action.value };
} else if (action.type === "description") {
return { ...state, product_discription: action.value };
} else if (action.type === "type") {
return { ...state, product_type: action.value };
}
};
const [state, dispatch] = useReducer(reducer, initialState);
const submitHandler = (e) => {
e.preventDefault();
const obj = {
product_id: state.product_id,
product_name: state.product_name,
product_price: +state.product_price,
product_title: state.product_title,
product_image: state.product_image,
product_type: state.product_type,
product_description: state.product_discription,
product_quantity: 0,
product_valid: "false",
};
console.log(obj);
// Dispatch(addProductHandler(obj));
// navigate(`/product`, { replace: true });
};
return (
<form onSubmit={submitHandler}>
<legend>
<center>
<h2>
<b>Add Product</b>
</h2>
</center>
</legend>
<div className="form-group">
<label>Product id</label>
<input
type="text"
className="form-control"
value={state.product_id}
onChange={(e) => dispatch({ type: "id", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Name</label>
<input
type="text"
className="form-control"
value={state.product_name}
onChange={(e) => dispatch({ type: "name", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Price</label>
<input
type="text"
className="form-control"
value={state.product_price}
onChange={(e) => dispatch({ type: "price", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Title</label>
<input
type="text"
className="form-control"
value={state.product_title}
onChange={(e) => dispatch({ type: "title", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Type</label>
<select
className="form-control"
value={state.product_type}
onChange={(e) => dispatch({ type: "type", value: e.target.value })}
>
<option value="" selected disabled>
Select one
</option>
<option value="c1">Commodityies</option>
<option value="g1">Gadgets</option>
<option value="w1">Wearings</option>
</select>
</div>
<div className="form-group">
<label>Product Image</label>
<input
type="file"
className="form-control"
value={state.product_image}
onChange={(e) => dispatch({ type: "image", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Description</label>
<textarea
className="form-control"
id=""
rows="7"
value={state.product_discription}
onChange={(e) =>
dispatch({ type: "description", value: e.target.value })
}
></textarea>
</div>
<button type="submit" className="btn btn-primary mt-4">
Submit
</button>
</form>
);
};
export default ProductForm;

you cannot upload file like that you should have to use FormData Class For multipart/form-data
var formData = new FormData();
formData.append('product_id', state.product_id,)
formData.append('product_name', state.product_name,)
formData.append('product_price', +state.product_price,)
formData.append('product_title', state.product_title,)
formData.append('product_image', state.product_image,)
formData.append('product_type', state.product_type,)
formData.append('product_description', state.product_discription,)
formData.append('product_quantity', 0,)
formData.append('product_valid', "false")
formData.append('image', $('input[type=file]')[0].files[0]);
$.ajax({
url: 'Your url here',
data: formData,
type: 'POST',
contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
processData: false, // NEEDED, DON'T OMIT THIS
// ... Other options like success and etc
});
After this it will send ajax request like you submit regular form
with enctype="multipart/form-data"

Related

onBlur, onChange, onClick on react is triggering twice

I am trying to build a form with react. But every onBlur, onChange, and onClick is triggering twice. It happens if i try to console log inside the reducer function. The JSX is -
import React, { useReducer } from "react";
const LongForm = () => {
const initialState = {
firstName: "",
lastName: "",
email: "",
gender: "",
education: "",
quantity: 0,
feedback: "",
term: false,
};
const reducer = (state, action) => {
switch (action.type) {
case "INPUT": {
return {
...state,
[action.payload.name]: action.payload.value,
};
}
case "TOGGLE": {
return {
...state,
term: !state.term,
};
}
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, initialState);
const submit = (event) => {
event.preventDefault();
};
return (
<div>
<form
onSubmit={submit}
>
<div>
<label htmlFor="firstName">
First Name
</label>
<input
type="text"
name="firstName"
id="firstName"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
</div>
<div>
<label htmlFor="lastName">
Last Name
</label>
<input
type="text"
name="lastName"
id="lastName"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
</div>
<div>
<label htmlFor="email">
Email
</label>
<input
type="email"
name="email"
id="email"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
</div>
<div>
<h1>Gender</h1>
<div>
<div>
<input
type="radio"
id="male"
name="gender"
value="male"
// prints twice
onClick={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
<label htmlFor="male">
Male
</label>
</div>
<div>
<input
type="radio"
id="female"
name="gender"
value="female"
// prints twice
onClick={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
<label htmlFor="female">
Female
</label>
</div>
<div>
<input
type="radio"
id="other"
name="gender"
value="other"
// prints twice
onClick={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
<label htmlFor="other">
Other
</label>
</div>
</div>
</div>
<div>
<label htmlFor="education">
Education
</label>
<select
name="education"
id="education"
// prints twice
onChange={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
>
<option value="SSC">SSC</option>
<option value="HSC">HSC</option>
<option value="underGrad">Under Graduate</option>
<option value="graduate">Graduate</option>
</select>
</div>
<div>
<label>Number of PCs</label>
<div>
<button>
-
</button>
<div>
<span>0</span>
</div>
<button>
+
</button>
</div>
</div>
<div>
<label htmlFor="feedback">
Feedback
</label>
<textarea
name="feedback"
id="feedback"
cols="30"
rows="4"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
></textarea>
</div>
<div>
<div>
<input
type="checkbox"
name="term"
id="terms"
// prints twice
onClick={() => dispatch({ type: "TOGGLE" })}
/>
<label htmlFor="terms">I agree to terms and conditions</label>
</div>
<button
type="submit"
>
Submit
</button>
</div>
</form>
</div>
);
};
export default LongForm;
I have looked into other problems But I am failing to understand why is it happening to my code. How can I solve this?
try to define these handlers as local functions inside your component. and check if your app wrapped with React.StrictMode

I cannot understand how setValue is working in init() which used in useEffect?

I know that useEffect( without any dependencies) only work on Mount So how state updates by setValues in init() here??
I am beginner in mern stack so please if you wnat any info please comment
//Code snippet
const init = () => {
getCategories().then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
categories: data,
formData: new FormData()
});
}
});
};
useEffect(() => {
init();
}, []);
//full code for help
import React, { useState, useEffect } from 'react';
import Layout from '../core/Layout';
import { isAuthenticated } from '../auth';
import { Link } from 'react-router-dom';
import { createProduct, getCategories } from './apiAdmin';
const AddProduct = () => {
const [values, setValues] = useState({
name: '',
description: '',
price: '',
categories: [],
category: '',
shipping: '',
quantity: '',
photo: '',
loading: false,
error: '',
createdProduct: '',
redirectToProfile: false,
formData: ''
});
const { user, token } = isAuthenticated();
const {
name,
description,
price,
categories,
category,
shipping,
quantity,
loading,
error,
createdProduct,
redirectToProfile,
formData
} = values;
// load categories and set form data
const init = () => {
getCategories().then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
categories: data,
formData: new FormData()
});
}
});
};
useEffect(() => {
init();
}, []);
const handleChange = name => event => {
const value = name === 'photo' ? event.target.files[0] : event.target.value;
formData.set(name, value);
setValues({ ...values, [name]: value });
};
const clickSubmit = event => {
event.preventDefault();
setValues({ ...values, error: '', loading: true });
createProduct(user._id, token, formData).then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
name: '',
description: '',
photo: '',
price: '',
quantity: '',
loading: false,
createdProduct: data.name
});
}
});
};
const newPostForm = () => (
<form className="mb-3" onSubmit={clickSubmit}>
<h4>Post Photo</h4>
<div className="form-group">
<label className="btn btn-secondary">
<input onChange={handleChange('photo')} type="file" name="photo" accept="image/*" />
</label>
</div>
<div className="form-group">
<label className="text-muted">Name</label>
<input onChange={handleChange('name')} type="text" className="form-control" value={name} />
</div>
<div className="form-group">
<label className="text-muted">Description</label>
<textarea onChange={handleChange('description')} className="form-control" value={description} />
</div>
<div className="form-group">
<label className="text-muted">Price</label>
<input onChange={handleChange('price')} type="number" className="form-control" value={price} />
</div>
<div className="form-group">
<label className="text-muted">Category</label>
<select onChange={handleChange('category')} className="form-control">
<option>Please select</option>
{categories &&
categories.map((c, i) => (
<option key={i} value={c._id}>
{c.name}
</option>
))}
</select>
</div>
<div className="form-group">
<label className="text-muted">Shipping</label>
<select onChange={handleChange('shipping')} className="form-control">
<option>Please select</option>
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div className="form-group">
<label className="text-muted">Quantity</label>
<input onChange={handleChange('quantity')} type="number" className="form-control" value={quantity} />
</div>
<button className="btn btn-outline-primary">Create Product</button>
</form>
);
const showError = () => (
<div className="alert alert-danger" style={{ display: error ? '' : 'none' }}>
{error}
</div>
);
const showSuccess = () => (
<div className="alert alert-info" style={{ display: createdProduct ? '' : 'none' }}>
<h2>{`${createdProduct}`} is created!</h2>
</div>
);
const showLoading = () =>
loading && (
<div className="alert alert-success">
<h2>Loading...</h2>
</div>
);
return (
<Layout title="Add a new product" description={`G'day ${user.name}, ready to add a new product?`}>
<div className="row">
<div className="col-md-8 offset-md-2">
{showLoading()}
{showSuccess()}
{showError()}
{newPostForm()}
</div>
</div>
</Layout>
);
};
export default AddProduct
You're right that the useEffect without any dependencies will run once on mount. So that means that the function init() is gonna be called at least once on mount, right? So whatever action you have in your init function will be called once. You don't need dependencies in order to set a state.

needing page to pull just one user based on ID for editing but get them all

This is my edit user page and I would like it to pull one user at a time for editing.
When you click the pencil to edit I would like just the one user pulled but instead I get all of them like in the second image.
in the code below I map them out but have tried using filter and a reducer but no fix has worked as of yet. would an inline condition be better like the one below but have not figured how to get the right ID from the URL.
{Collectors.CollectorID === Collectors.CollectorID && <div><h2>1-30 days past due in Tandem – all credit types</h2> <p>{Collectors.CollectorCode}{Collectors.FinanceCompany}</p></div>}
import React from "react";
import axios from 'axios';
class UpdateUser extends React.Component {
constructor(props) {
super(props);
this.state = {
collectorList: [],
CollectorID: props.CollectorID,
ProgramBucketID: props.ProgramBucketID,
CollectorOptionsID: props.CollectorOptionsID,
FinanceCompanyID: props.FinanceCompanyID,
Active: '',
LastName: '',
CollectorCode: '',
Aging1to15: '',
Aging31to45: '',
Aging31to60: '',
AgingOver60: '',
ProgramBucketA: '',
ProgramBucketB: '',
ProgramBucketC: '',
ProgramBucketSU: '',
FinanceCompany: ''
}
this.handleActiveChange = this.handleActiveChange.bind(this);
this.handleAging115Change = this.handleAging115Change.bind(this);
this.handleAging3145Change = this.handleAging3145Change.bind(this);
this.handleAging3160Change = this.handleAging3160Change.bind(this);
this.handleAgingOver60Change = this.handleAgingOver60Change.bind(this);
this.handleProgramAChange = this.handleProgramAChange.bind(this);
this.handleProgramBChange = this.handleProgramBChange.bind(this);
this.handleProgramCChange = this.handleProgramCChange.bind(this);
this.handleProgramSUChange = this.handleProgramSUChange.bind(this);
}
componentDidMount(e) {
this.getCollectors()
}
handleActiveChange(e) {
this.setState({
Active: !this.state.Active
})
}
handleAging115Change() {
this.setState({
Aging1to15: !this.state.Aging1to15
})
}
handleAging3145Change() {
this.setState({
Aging31to45: !this.state.Aging31to45
})
}
handleAging3160Change() {
this.setState({
Aging31to60: !this.state.Aging31to60
})
}
handleAgingOver60Change() {
this.setState({
AgingOver60: !this.state.AgingOver60
})
}
handleProgramAChange() {
this.setState({
ProgramBucketA: !this.state.ProgramBucketA
})
}
handleProgramBChange() {
this.setState({
ProgramBucketB: !this.state.ProgramBucketB
})
}
handleProgramCChange() {
this.setState({
ProgramBucketC: !this.state.ProgramBucketC
})
}
handleProgramSUChange() {
this.setState({
ProgramBucketSU: !this.state.ProgramBucketSU
})
}
getCollectors = () => {
axios.get(`http://localhost:5000/getCollectors`)
.then((result) => result.data)
.then((result) => {
this.setState({collectorList: result});
});
};
onUpdateClick = CollectorID => {
axios.put(`http://localhost:5000/UpdateUser/${CollectorID}`, {
CollectorID: this.state.CollectorID,
CollectorOptionsID: this.state.CollectorOptionsID,
ProgramBucketID: this.state.ProgramBucketID,
FinanceCompanyID: this.state.FinanceCompanyID,
Active: this.state.Active,
LastName: this.state.LastName,
CollectorCode: this.state.CollectorCode,
Aging1to15: this.state.Aging1to15,
Aging31to45: this.state.Aging31to45,
Aging31to60: this.state.Aging31to60,
AgingOver60: this.state.AgingOver60,
ProgramBucketA: this.state.ProgramBucketA,
ProgramBucketB: this.state.ProgramBucketB,
ProgramBucketC: this.state.ProgramBucketC,
ProgramBucketSU: this.state.ProgramBucketSU,
FinanceCompany: this.state.FinanceCompany
});
};
render() {
// console.log(this.state);
return (
<div>
<h1>Update Collectors</h1>
<div className="wrapper">
{this.state.collectorList.map((Collectors) => (
<form className="updateUserForm" key={Collectors.CollectorID}>
<div className="updateUserItem">
<b>{Collectors.FirstName} {Collectors.LastName} | {Collectors.CollectorCode}</b>
{/*Active or inactive User*/}
<label>Active Status</label>
<input
type='checkbox'
name="Active"
value={this.state.Active}
defaultChecked={Collectors.Active === false ? false : true}
onChange={this.handleActiveChange}
/>
{/*Collector Last Name*/}
<label>Last Name</label>
<input
type="text"
name="LastName"
defaultValue={Collectors.LastName}
onChange={e => this.setState({
LastName: e.target.value
})}
/>
{/*Collector Code First Initial Middle Initial Last Initial*/}
<label>Collector Code</label>
<input
type="text"
name="CollectorCode"
defaultValue={Collectors.CollectorCode}
onChange={e => this.setState({
CollectorCode: e.target.value
})}
/>
{/*Aging Bucket selection section */}
<label>Aging Bucket</label>
<div className='newUserCheckboxContainer'>
<label className='newUserCheckboxLabel'>1-15<br/>
<input
type='checkbox'
className='AgingBucketCheckbox'
value={this.state.Aging1to15}
defaultChecked={Collectors.Aging1to15 === false ? false : true}
onChange={this.handleAging115Change}
/></label>
<label className='newUserCheckboxLabel'>31-45<br/>
<input
type='checkbox'
className='AgingBucketCheckbox'
value={this.state.Aging31to45}
defaultChecked={Collectors.Aging31to45 === false ? false : true}
onChange={this.handleAging3145Change}
/></label>
<label className='newUserCheckboxLabel'>31-60<br/>
<input
type='checkbox'
className='AgingBucketCheckboxsm'
value={this.state.Aging31to60}
defaultChecked={Collectors.Aging31to60 === false ? false : true}
onChange={this.handleAging3160Change}
/></label>
<label className='newUserCheckboxLabel'>Over 60<br/>
<input
type='checkbox'
className='AgingBucketCheckboxlg'
value={this.state.AgingOver60}
defaultChecked={Collectors.AgingOver60 === false ? false : true}
onChange={this.handleAgingOver60Change}
/></label>
</div>
{/*Progam code selection section*/}
<label>Program Bucket</label>
<div className='newUserCheckboxContainer'>
<label className='newUserCheckboxLabel'>A<br/>
<input
type='checkbox'
className='ProgramBucketChecbox'
value={this.state.ProgramBucketA}
defaultChecked={Collectors.ProgramBucketA === false ? false : true}
onChange={this.handleProgramAChange}
/></label>
<label className='newUserCheckboxLabel'>B<br/>
<input
type='checkbox'
className='ProgramBucketChecbox'
value={this.state.ProgramBucketB}
defaultChecked={Collectors.ProgramBucketB === false ? false : true}
onChange={this.handleProgramBChange}
/></label>
<label className='newUserCheckboxLabel'>C<br/>
<input
type='checkbox'
className='ProgramBucketChecbox'
value={this.state.ProgramBucketC}
defaultChecked={Collectors.ProgramBucketC === false ? false : true}
onChange={this.handleProgramCChange}
/></label>
<label className='newUserCheckboxLabel'>SU<br/>
<input
type='checkbox'
className='ProgramBucketChecbox'
value={this.state.ProgramBucketSU}
defaultChecked={Collectors.ProgramBucketSU === false ? false : true}
onChange={this.handleProgramSUChange}
/></label>
</div>
{/*Finance Company selection section*/}
<label>Finance Company</label>
<div className='newUserCheckboxContainer'>
<label className='newUserCheckboxLabel'>
<input
type="text"
name="FinanceCompany"
defaultValue={Collectors.FinanceCompany}
onChange={e => this.setState({
FinanceCompany: e.target.value
})}
/></label>
</div>
<button className="updateUserButton" onClick={() => this.onUpdateClick(Collectors.CollectorID) }>Update User</button>
</div>
</form>
))}
</div>
</div>
);
}
}
export default UpdateUser;
After going through some tests I found the below code works wonderfully if anyone is having this issue.
import React, { useState, useEffect } from "react";
import axios from "axios";
import { useParams } from "react-router-dom";
const UpdateUser = () => {
const { CollectorID } = useParams();
const [user, setUser] = useState({
Active: '',
FirstName: '',
LastName: '',
CollectorCode: ''
});
const { Active, FirstName, LastName, CollectorCode } = undefined || user;
const onInputChange = e => {
setUser({
...user, [e.target.name]: e.target.value,
Active: !Active });
};
useEffect(() => {
loadUser();
}, []);// eslint-disable-line react-hooks/exhaustive-deps
const loadUser = async () => {
const result = await axios.get(`http://localhost:5000/getCollectors/${CollectorID}`);
setUser(result.data[CollectorID - 1]);
// console.log(result.data[CollectorID - 1]);
};
const onSubmit = async e => {
e.preventDefault();
await axios.put(`http://localhost:5000/UpdateUser/${CollectorID}`, {
CollectorID: CollectorID,
Active: Active,
LastName: LastName,
CollectorCode: CollectorCode
});
console.log(CollectorID, Active, LastName, CollectorCode)
};
return (
<div className="previewWrapper">
<h1>Update Collector</h1>
{FirstName} {LastName} | {CollectorCode} - {CollectorID} {console.log(user)}
<form className="newUserForm" onSubmit={e => onSubmit(e)}>
<div className="newUserItem">
{/*Active or inactive User*/}
<label>Active</label>
<input
type='checkbox'
defaultValue={Active}
defaultChecked={Active}
onChange={e => onInputChange(e)}
/>
{/*Collector Last Name*/}
<label>Last Name</label>
<input
type="text"
placeholder="Last Name"
name="LastName"
defaultValue={LastName}
onChange={e => onInputChange(e)}
/>
{/*Collector Code First Initial Middle Initial Last Initial*/}
<label>Collector Code</label>
<input
type="text"
name="CollectorCode"
placeholder="Collector Code"
defaultValue={CollectorCode}
onChange={e => onInputChange(e)}
/>
<button className="newUserButton">Update Collector</button>
</div>
</form>
</div>
);
}
export default UpdateUser;

value of the option selected not passing in react

Trying to get a response when clicking and store the selected option from the selected value genre, not sure how to add a select new state variable or a post method. When the option is clicked the click handler is not called with the selected options so that we can add it to the state. My genre is also seen as undefined when I don't click on the the text type.
Feedback.js
import React, { useState } from "react";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.min.css";
import Layout from "./Layout";
const Feedback = () => {
const [values, setValues] = useState({
name: "",
artist: "",
songTitle: "",
email: "",
message: "",
phone: "",
genre: "",
uploadedFiles: [],
buttonText: "Submit",
uploadPhotosButtonText: "Upload files",
});
// destructure state variables
const {
name,
artist,
songTitle,
label,
email,
message,
phone,
genre,
uploadedFiles,
buttonText,
uploadPhotosButtonText,
} = values;
// destructure env variables
const {
REACT_APP_API,
REACT_APP_CLOUDINARY_CLOUD_NAME,
REACT_APP_CLOUDINARY_UPLOAD_SECRET,
} = process.env;
// event handler
const handleChange = (name) => (event) => {
setValues({ ...values, [name]: event.target.value });
};
const handleSubmit = (event) => {
event.preventDefault();
setValues({ ...values, buttonText: "...sending" });
// send to backend for email
console.table({ name, email, phone, message, uploadedFiles, genre });
axios({
method: "POST",
url: `${REACT_APP_API}/feedback`,
data: {
name,
artist,
songTitle,
label,
email,
genre,
phone,
message,
uploadedFiles,
},
})
.then((response) => {
// console.log('feedback submit response', response);
if (response.data.success) toast.success("Thanks for your feedback");
setValues({
...values,
name: "",
artist: "",
songTitle: "",
label: "",
phone: "",
email: "",
genre: "",
message: "",
uploadedFiles: [],
buttonText: "Submitted",
uploadPhotosButtonText: "Uploaded",
});
})
.catch((error) => {
// console.log('feedback submit error', error.response);
if (error.response.data.error) toast.error("Failed! Try again!");
});
};
function onChangeInput(value) {
console.log(value);
}
const uploadWidget = () => {
window.cloudinary.openUploadWidget(
{
cloud_name: REACT_APP_CLOUDINARY_CLOUD_NAME,
upload_preset: REACT_APP_CLOUDINARY_UPLOAD_SECRET,
tags: ["ebooks"],
},
function (error, result) {
// console.log(result);
setValues({
...values,
uploadedFiles: result,
uploadPhotosButtonText: `${
result ? result.length : 0
} Photos uploaded`,
});
}
);
};
const feedbackForm = () => (
<React.Fragment>
<div className="form-group">
<button
onClick={() => uploadWidget()}
className="btn btn-outline-secondary btn-block p-5"
>
{uploadPhotosButtonText}
</button>
</div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="text-muted">Description</label>
<textarea
onChange={handleChange("message")}
type="text"
className="form-control"
value={message}
required
></textarea>
</div>
<div className="form-group">
<label className="text-muted">Your Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("name")}
value={name}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Your Email</label>
<input
className="form-control"
type="email"
onChange={handleChange("email")}
value={email}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Your Phone</label>
<input
className="form-control"
type="number"
onChange={handleChange("phone")}
value={phone}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Artist Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("artist")}
value={artist}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Song Title</label>
<input
className="form-control"
type="text"
onChange={handleChange("songTitle")}
value={songTitle}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Record Label Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("label")}
value={label}
/>
</div>
<div className="form-group">
<label className="text-muted">Music Genre:</label>
<select
className="form-control"
value={genre}
type="select"
onChange={handleChange("genre")}
>
<option value="steak">Steak</option>
<option value="sandwich">Sandwich</option>
<option value="dumpling">Dumpling</option>
</select>
</div>
<button className="btn btn-outline-primary btn-block">
{buttonText}
</button>
</form>
</React.Fragment>
);
return (
<Layout>
<ToastContainer />
<div className="container text-center">
<h1 className="p-5">Feedback Online</h1>
</div>
<div className="container col-md-8 offset-md-2">{feedbackForm()}</div>
<br />
<br />
<br />
</Layout>
);
};
export default Feedback;

why am i getting undefined for match object in react.js

The below code is to update a product in admin panel. I have manage to do everything except that on a button pressed for update i want to fetch the url from the above address bar. I thought of using match.params.productId. Here produtId is what i wanted ti get. But i dont know why the match object returns undefined..PLease help me to get rid of this.
import React, { useState, useEffect } from "react";
import Base from "../core/Base";
import { Link } from "react-router-dom";
import {
getAllCategories,
getProduct,
updateProduct
} from "./helper/adminapicall";
import { isAuthenticated } from "../auth/helper/index";
const UpdateProduct = ({ match }) => {
const { user, token } = isAuthenticated();
const [values, setValues] = useState({
name: "",
description: "",
price: "",
stock: "",
photo: "",
categories: [],
category: "",
loading: false,
error: "",
createdProduct: "",
getaRedirect: false,
formData: ""
});
const {
name,
description,
price,
stock,
categories,
category,
loading,
error,
createdProduct,
getaRedirect,
formData
} = values;
const preload = (productId) => {
getProduct(productId).then((data) => {
console.log(data);
if (data.error) {
setValues({ ...values, error: data.error });
} else {
preloadCategories();
setValues({
...values,
name: data.name,
description: data.description,
price: data.price,
category: data.category._id,
stock: data.stock,
formData: new FormData()
});
}
});
};
const preloadCategories = () => {
getAllCategories().then((data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
categories: data,
formData: new FormData()
});
}
});
};
useEffect(() => {
//console.log(match);
preload(match.params.productId);
}, []);
//TODO: work on it
const onSubmit = (event) => {
event.preventDefault();
setValues({ ...values, error: "", loading: true });
updateProduct(match.params.productId, user._id, token, formData).then(
(data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
name: "",
description: "",
price: "",
photo: "",
stock: "",
loading: false,
createdProduct: data.name
});
}
}
);
};
const handleChange = (name) => (event) => {
const value = name === "photo" ? event.target.files[0] : event.target.value;
formData.set(name, value);
setValues({ ...values, [name]: value });
};
const successMessage = () => (
<div
className="alert alert-success mt-3"
style={{ display: createdProduct ? "" : "none" }}
>
<h4>{createdProduct} updated successfully</h4>
</div>
);
const createProductForm = () => (
<form>
<span>Post photo</span>
<div className="form-group">
<label className="btn btn-block btn-success">
<input
onChange={handleChange("photo")}
type="file"
name="photo"
accept="image"
placeholder="choose a file"
/>
</label>
</div>
<div className="form-group">
<input
onChange={handleChange("name")}
name="photo"
className="form-control"
placeholder="Name"
value={name}
/>
</div>
<div className="form-group">
<textarea
onChange={handleChange("description")}
name="photo"
className="form-control"
placeholder="Description"
value={description}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("price")}
type="number"
className="form-control"
placeholder="Price"
value={price}
/>
</div>
<div className="form-group">
<select
onChange={handleChange("category")}
className="form-control"
placeholder="Category"
>
<option>Select</option>
{categories &&
categories.map((cate, index) => (
<option key={index} value={cate._id}>
{cate.name}
</option>
))}
</select>
</div>
<div className="form-group">
<input
onChange={handleChange("stock")}
type="number"
className="form-control"
placeholder="Stock"
value={stock}
/>
</div>
<button
type="submit"
onClick={onSubmit}
className="btn btn-outline-success mb-3"
>
Update Product
</button>
</form>
);
return (
<Base
title="Add a product here!"
description="Welcome to product creation section"
className="container bg-info p-4"
>
<Link to="/admin/dashboard" className="btn btn-md btn-dark mb-3">
Admin Home
</Link>
<div className="row bg-dark text-white rounded">
<div className="col-md-8 offset-md-2">
{successMessage()}
{createProductForm()}
</div>
</div>
</Base>
);
};
export default UpdateProduct;

Resources