Issue
Good afternoon Devs.
My Problem:
I need to read data returned from an ion modal in the parent page. Specifically, I Want to await a user entering some text on an ion modal and when the user clicks ok, the page can read and use the entered data returned from the modal. I need to await as I need the data from the modal before i can proceed with processing. As a note, I am using TypeScript on an ionic react project.
Things I've tried: I looked through various sites and it is suggested that I can get data by listening to the onDidDismiss event. I have tried this but I get no data (I have also tried waiting for a promise to resolve and look for data in the .then ) It seems the documentation says that the dismiss() function for useIonModal allows data to be passed as a prop, but the code will not allow args to the dismiss function.
I have some code snipptes below to illustrate my code so far
const ModalBody = ()=>{
const [text,setText] = useState<string>("")
const Dismiss=(data:{isText:boolean, note:string})=>{handleDismiss(data)}
return(
<div>
<div className={"ion-text-center ion-padding"}>
<IonTitle>Enter Your Data Here</IonTitle>
<IonTextarea
rows={10}
inputMode="text"
spellCheck={true}
maxlength={2000}
className={"ReasonBox"}
onIonChange={(e)=>setText(e.detail.value!)}
/>
</div>
<div className={"modalButton"}>
<IonButton expand={"block"} color="logoText" onClick={()=>Dismiss({isText:true,note:text})}>Save</IonButton>
<IonButton color="logoText" expand="block" onClick={()=>handleDismiss({isText:false,note:""})}>Cancel</IonButton>
</div>
</div>
)
}
const [present, dismiss] = useIonModal(ModalBody); // Where ModalBody is my component
const noteModal =():Promise<boolean>=>{
return new Promise((resolve, reject)=>{
const conf = present({
cssClass: 'my-css',
onDidDismiss: async (e) =>{
console.log("modal test" , e); //get all event stuff, but no data
resolve(true)
}
})
})
}
const handleDismiss=(data:{isText:boolean, note:string})=>{
console.log(data.note, data.isText); //i have got data here but how to send it to my noteModal function?
dismiss();
})
}
What am I missing here? I assume I want to set some data to the modal so I can access it in the onDidDismiss event, or is there a better way? any help is greatly appreciated
Solution
this is the pattern I use... provide a callback function for when you are closing the modal and pass the data back through that function
Modal is opened by setting the state variable modalOpen
using setModalOpen(true)
// code in the template
<IonModal isOpen={modalOpen}>
<AddStudentModal
onCloseModal={handleModalClose}
initialData={modalData}
/>
</IonModal>
The code from the modal, data is passed in, and the callback function onCloseModal
const AddStudentModal = ({ onCloseModal, initialData }) => {
const [section, setSection] = useState();
const [name, setName] = useState();
useEffect(() => {
setSection(initialData?.section);
setName(initialData?.name);
}, []);
// if user cancels, close and pass back null
const handleCancel = () => {
onCloseModal(null);
};
// if user has data, cloe and pass back the appropriate data
const handleSave = () => {
onCloseModal({
name,
section,
id: initialData?.id
});
};
return (
<IonPage>
<IonHeader>
<IonToolbar />
</IonHeader>
<IonContent className="ion-padding">
<strong>Ready to create an app?</strong>
<IonItem>
<IonLabel>Name</IonLabel>
<IonInput value={name} onIonChange={e => setName(e.detail.value)} />
</IonItem>
<IonItem>
<IonLabel>Section</IonLabel>
<IonSelect
value={section}
placeholder="Select One"
onIonChange={e => setSection(e.detail.value)}
>
<IonSelectOption value="advanced">Advanced</IonSelectOption>
<IonSelectOption value="beginners">Beginners</IonSelectOption>
</IonSelect>
</IonItem>
<div style={{ paddingTop: 10 }}>
<IonButton onClick={handleSave}>SAVE STUDENT</IonButton>
<IonButton onClick={handleCancel} color="danger">
CANCEL
</IonButton>
</div>
</IonContent>
</IonPage>
);
};
The code in the parent component to handle the closing of the modal, set response to null when the user selects cancel
const handleModalClose = response => {
setModalOpen(false);
if (response) {
console.log(response);
if (response.id) {
updateStudent({
name: response.name,
section: response.section,
id: response.id
});
} else {
addStudent({ name: response.name, section: response.section });
}
}
modalData && setModalData(null);
};
Working Stackblitz with complete example
Video Tutorial
Answered By - Aaron Saunders
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.