Reputation: 500
I have a react component
import React from "react";
import { AgreementInfo } from "../../../../models/shop";
import { MdClose } from "react-icons/md";
import moment from "moment";
import { uploadImageCore } from "utils/image";
type AgreementInfoProps = {
setFieldValue(agreement_code: string, val: AgreementInfo[]): void;
kps: AgreementInfo[];
index: number;
kp: AgreementInfo;
};
export const Agreement = ({
setFieldValue,
kps,
index,
kp,
}: AgreementInfoProps): JSX.Element => {
const [agreementCopy, setAgreementCopy] = React.useState("");
const handleImageChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.currentTarget.files);
const files = e.currentTarget.files ?? "";
console.log({ files });
const res = await uploadImageCore(files[0]);
console.log({ res });
const agreementInfos = [...kps];
console.log({ agreementInfos });
const newCopy = setAgreementCopy(res.data.data.url);
console.log({ agreementCopy });
console.log({ newCopy });
agreementInfos[index].agreement_scan_copy = agreementCopy;
setFieldValue("agreement_info", [...agreementInfos]);
};
return (
<>
<div className="grid grid-cols-2 gap-4 w-full">
<div>
<label className="block mr-4">
<input
placeholder="Agreement code"
value={kp.agreement_code}
className="block w-full form-input"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const agreementInfos = [...kps];
agreementInfos[index].agreement_code = e.target.value;
setFieldValue("agreement_info", [...agreementInfos]);
}}
/>
</label>
</div>
<div>
<label className="block mr-4">
<input
className="block w-full form-input"
onChange={(e) => handleImageChange(e)}
type="file"
/>
</label>
</div>
<div>
<label className="block">
<input
placeholder="Agreement Expairy Date"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const agreementInfos = [...kps];
agreementInfos[index].agreement_expiry_date = e.target.value;
setFieldValue("agreement_info", [...agreementInfos]);
}}
type="date"
value={moment(kp.agreement_expiry_date).format("YYYY-MM-DD")}
className="block w-full form-input"
/>
</label>
</div>
<div>
<label className="block mr-4">
<input
placeholder="Credit Limit"
value={kp.credit_limit}
className="block w-full form-input"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const agreementInfos = [...kps];
agreementInfos[index].credit_limit = parseInt(e.target.value);
setFieldValue("agreement_info", [...agreementInfos]);
}}
/>
</label>
</div>
<div>
<label className="block mr-4">
<input
placeholder="Credit Time"
value={kp.credit_time}
className="block w-full form-input"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const agreementInfos = [...kps];
agreementInfos[index].credit_time = parseInt(e.target.value);
setFieldValue("agreement_info", [...agreementInfos]);
}}
/>
</label>
</div>
</div>
<button
type="button"
onClick={() =>
setFieldValue(
"agreement_info",
kps.filter((_, kpIndex: number) => kpIndex !== index)
)
}
className="p-2 ml-4 text-gray-500 rounded-full hover:bg-gray-600 hover:text-white"
>
<MdClose />
</button>
</>
);
};
I want to set data of agreement_scan_copy
in the state agreementCopy
. But I can not pass the data in this current implementation. This Agreement
component will be used to show data in the form of an Array in another component. This is the component
import { FormikProps, FormikValues, Field } from "formik";
import "styled-components/macro";
import { KeyPerson } from "../../../../shop/component/create/KeyPerson";
import { Acquisition } from "../../../../shop/component/create/Acquisition";
import { Agreement } from "../../../../shop/component/create/Agreement";
import { CategoryHead } from "../../../../shop/component/create/CategoryHead";
import { BDM } from "../../../../shop/component/create/BDM";
import { KAM } from "../../../../shop/component/create/KAM";
import { VM } from "../../../../shop/component/create/VM";
export const inputClass =
"rounded bg-gray-100 px-2 py-2 focus:bg-white border border-gray-100 focus:border-black block w-full";
export default function AdditionalInformations({
formikBag,
}: {
formikBag: FormikProps<FormikValues>;
}): JSX.Element {
return (
<div className="py-10 px-6">
<div className="flex flex-row justify-between">
<div className="mb-6">
<>
<div className="grid grid-cols-2 gap-4 w-full">
<div className="mb-6">
<label htmlFor={"organisation_type"}>
{"Organization Type"}
</label>
<Field
as="select"
name="organisation_type"
className="form-select"
>
<option value="small">Small</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
</Field>
</div>
<div className="mb-6">
<label htmlFor={"bin_no"}>{"BIN No"}</label>
<Field
type="number"
name="bin_no"
id="bin_no"
className={"form-input"}
/>
</div>
<div className="mb-6">
<label htmlFor={"trade_license_no"}>{"Trade License No"}</label>
<Field
type="text"
name="trade_license_no"
id="trade_license_no"
className={"form-input"}
/>
</div>
</div>
<div className="block mb-6">
<p className="mb-2">
Key Personnel
<button
type="button"
onClick={() =>
formikBag.setFieldValue("key_personnel", [
...formikBag.values.key_personnel,
{
username: "",
designation: "",
phone_no: "",
email: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add Key Personnel
</button>
</p>
{formikBag.values.key_personnel.map(
(
kp: {
username: string;
designation: string;
phone_no: string;
email: string;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<KeyPerson
setFieldValue={formikBag.setFieldValue}
kps={formikBag.values.key_personnel}
index={index}
kp={kp}
/>
</div>
)
)}
</div>
<div className="grid grid-cols-2 gap-4 w-full">
<div className="block mb-6">
<p className="mb-2">
<b>Category Head</b>
<button
type="button"
onClick={() =>
formikBag.setFieldValue("category_head", [
...formikBag.values.category_head,
{
username: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add Category Head
</button>
</p>
{formikBag.values.category_head.map(
(
ch: {
username: string;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<CategoryHead
setFieldValue={formikBag.setFieldValue}
chs={formikBag.values.category_head}
index={index}
ch={ch}
/>
</div>
)
)}
</div>
<div className="block mb-6">
<p className="mb-2">
<b>BDM</b>
<button
type="button"
onClick={() =>
formikBag.setFieldValue("bdm", [
...formikBag.values.bdm,
{
username: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add BDM
</button>
</p>
{formikBag.values.bdm.map(
(
bdm: {
username: string;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<BDM
setFieldValue={formikBag.setFieldValue}
bdms={formikBag.values.bdm}
index={index}
bdm={bdm}
/>
</div>
)
)}
</div>
<div className="block mb-6">
<p className="mb-2">
<b>KAM</b>
<button
type="button"
onClick={() =>
formikBag.setFieldValue("kam", [
...formikBag.values.kam,
{
username: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add KAM
</button>
</p>
{formikBag.values.kam.map(
(
kam: {
username: string;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<KAM
setFieldValue={formikBag.setFieldValue}
kams={formikBag.values.kam}
index={index}
kam={kam}
/>
</div>
)
)}
</div>
<div className="block mb-6">
<p className="mb-2">
<b>VM</b>
<button
type="button"
onClick={() =>
formikBag.setFieldValue("vm", [
...formikBag.values.vm,
{
username: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add VM
</button>
</p>
{formikBag.values.vm.map(
(
vm: {
username: string;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<VM
setFieldValue={formikBag.setFieldValue}
vms={formikBag.values.vm}
index={index}
vm={vm}
/>
</div>
)
)}
</div>
</div>
<div className="block mb-6">
<p className="mb-2">
Acquisition Info
<button
type="button"
onClick={() =>
formikBag.setFieldValue("acquisition_info", [
...formikBag.values.acquisition_info,
{
acquisition_code: "",
acquisition_by: "",
acquisition_phone_no: "",
acquisition_email: "",
acquisition_date: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add Acquisition Info
</button>
</p>
{formikBag.values.acquisition_info.map(
(
kp: {
acquisition_code: string;
acquisition_by: string;
acquisition_phone_no: string;
acquisition_email: string;
acquisition_date: string;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<Acquisition
setFieldValue={formikBag.setFieldValue}
kps={formikBag.values.acquisition_info}
index={index}
kp={kp}
/>
</div>
)
)}
</div>
<div className="block mb-6">
<p className="mb-2">
Agreement Info
<button
type="button"
onClick={() =>
formikBag.setFieldValue("agreement_info", [
...formikBag.values.agreement_info,
{
agreement_code: "",
agreement_scan_copy: "",
agreement_expiry_date: "",
credit_limit: "",
credit_time: "",
},
])
}
className="float-right ml-4 text-sm underline"
>
Add Agreement Info
</button>
</p>
{formikBag.values.agreement_info.map(
(
kp: {
agreement_code: string;
agreement_scan_copy: string;
agreement_expiry_date: string;
credit_limit: number;
credit_time: number;
},
index: number
) => (
<div
key={index}
className="flex items-center p-4 mt-2 bg-gray-100 rounded"
>
<Agreement
setFieldValue={formikBag.setFieldValue}
kps={formikBag.values.agreement_info}
index={index}
kp={kp}
/>
</div>
)
)}
</div>
<div className="grid grid-cols-2 gap-4 w-full">
<div>
<label htmlFor={"bank_account_name"}>
{"Bank Account Name"}
</label>
<Field
type="text"
name="bank_account_name"
id="bank_account_name"
className={"form-input"}
/>
</div>
<div>
<label htmlFor={"bank_account_no"}>{"Bank Account No"}</label>
<Field
type="number"
name="bank_account_no"
id="bank_account_no"
className={"form-input"}
/>
</div>
<div>
<label htmlFor={"bank_name"}>{"Bank Name"}</label>
<Field
type="text"
name="bank_name"
id="bank_name"
className={"form-input"}
/>
</div>
<div>
<label htmlFor={"bank_branch_name"}>{"Bank Branch Name"}</label>
<Field
type="text"
name="bank_branch_name"
id="bank_branch_name"
className={"form-input"}
/>
</div>
<div>
<label htmlFor={"bank_branch_routing_no"}>
{"Bank Branch Routing No"}
</label>
<Field
type="number"
name="bank_branch_routing_no"
id="bank_branch_routing_no"
className={"form-input"}
/>
</div>
<div>
<label htmlFor={"sbu_unit"}>{"SBU Unit"}</label>
<Field
type="text"
name="sbu_unit"
id="sbu_unit"
className={"form-input"}
/>
</div>
</div>
</>
</div>
</div>
</div>
);
}
So the data structure of the Agreement
Array is
{
agreement_code: "",
agreement_scan_copy: "",
agreement_expiry_date: "",
credit_limit: "",
credit_time: "",
}
so now I want to set the data in the agreement_scan_copy
key from the Agreement
component and then POST in an API. But the above code does not set the value in the array. These are the console logs
FileList {0: File, length: 1}
0: File
lastModified: 1618304176889
lastModifiedDate: Tue Apr 13 2021 14:56:16 GMT+0600 (Bangladesh Standard Time) {}
name: "ehealth.png"
size: 4276
type: "image/png"
webkitRelativePath: ""
__proto__: File
length: 1
__proto__: FileList
res:
config: {url: "https://api-dev.evaly.com.bd/core/image/upload", method: "post", data: FormData, headers: {…}, transformRequest: Array(1), …}
data:
data:
url: "https://s3-ap-southeast-1.amazonaws.com/media.evaly.com.bd/media/images/d26acdb48506-ehealth.png"
url_sm: "https://df17fp68uwcso.cloudfront.net/eyJidWNrZXQiOiAibWVkaWEuZXZhbHkuY29tLmJkIiwgImtleSI6ICJtZWRpYS9pbWFnZXMvZDI2YWNkYjQ4NTA2LWVoZWFsdGgucG5nIiwgImVkaXRzIjogeyJyZXNpemUiOiB7IndpZHRoIjogMTUwLCAiaGVpZ2h0IjogMTUwLCAiZml0IjogImNvbnRhaW4ifSwgImJhY2tncm91bmQiOiB7InIiOiAyNTUsICJnIjogMjU1LCAiYiI6IDI1NSwgImFscGhhIjogMX0sICJmbGF0dGVuIjogdHJ1ZSwgImpwZWciOiB7InF1YWxpdHkiOiA3NX19fQ=="
__proto__: Object
message: "Image upload successful"
success: true
__proto__: Object
headers: {content-length: "551", content-type: "application/json"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 201
statusText: "Created"
__proto__: Object
__proto__: Object
agreementInfos: Array(2)
0:
agreement_code: "ert8909"
agreement_expiry_date: "2021-06-05"
agreement_scan_copy: ""
credit_limit: 20
credit_time: 5
__proto__: Object
1:
agreement_code: "tyu3456"
agreement_expiry_date: "2021-06-05"
agreement_scan_copy: ""
credit_limit: 30
credit_time: 15
__proto__: Object
length: 2
__proto__: Array(0)
__proto__: Object
agreementCopy: ""
newCopy: undefined
how can I set the agreement_scan_copy
image data in the agreementInfos
Array?
uploadImageCore Component is here
export async function uploadImageCore(file: any) {
const form = new FormData();
form.append("image", file, file.name);
try {
const apiUrl = baseUrl.URL_CORE + "/image/upload";
const res = await axios.post(apiUrl, form, {
headers: {
Authorization: "Bearer " + getTokenFromCookies(), //the token is a variable which holds the token
},
});
if (equals(res.status, 201)) {
return Promise.resolve(res);
} else {
return Promise.reject();
}
} catch (error) {
// console.log(error);
return Promise.reject(error.response.data);
}
}
Upvotes: 0
Views: 64
Reputation: 36
Why do you need a state here? Can't you just do agreementInfos[index].agreement_scan_copy = res.data.data.url;
?
Upvotes: 1