cannot read property 'function name' of undefined React js - javascript

im working with the modal from https://react-bootstrap.netlify.app/components/modal/ and basically i've managed to display a modal from a button that i click. However inside the modal there's another button that when i click should perform a task i've defined in a function already. Now when i click this button in the modal i get the error cannot read property 'confirm_booking' of undefined Here is my code.
constructor(props){
super(props)
this.state={
setModalShow_available_room: false,
modalShow_available_room: false
}
this.confirm_booking = this.confirm_booking.bind(this)
}
render (){
function Available_room_modal(props) {
return (
<Modal
{...props}
size="sm"
aria-labelledby="contained-modal-title-vcenter"
centered>
<Modal.Body>
<Button block onClick={() => { this.confirm_booking() }} >Confirm</Button>
</Modal.Body>
</Modal>
);
}
return(
<div>
<Button block onClick={() => { this.open_modal() }} >Show modal</Button>
<Available_room_modal
show={this.state.modalShow_available_room}
onHide={() => {
this.setState({ setModalShow_available_room: false })
this.setState({ modalShow_available_room: false })
}} />
</div>
)
}
/**then for my functions **/
/**this opens the modal **/
open_modal() {
this.setState({ setModalShow_available_room: true })
this.setState({ modalShow_available_room: true })
}
/**this is the function assigned to the button inside the modal which throws an error when i click it**/
confirm_booking() {
this.setState({ setModalShow_available_room: false })
this.setState({ modalShow_available_room: false })
}

you are clearly not understanding how react works. Please try to see the react documentation first.
I will try to show you some of your errors:
You can't declare a function inside render method. Render method is just to return JSX code. You could declare a function in the class, return jsx from there and call it from render, that is valid.
<Button block onClick={() => { this.confirm_booking() }} >Confirm</Button>
Here, you are calling this.confirm_booking EVERY time your component is being rendered. You should change it to this:
<Button block onClick={this.confirm_booking}> Confirm </Button>

Related

How to fix the Property 'setConfirmDelete' does not exist on type 'JSX.IntrinsicElements' in reactjs

index.tsx
const setConfirmDelete = (state, close) => {
return (
<Modal show={state} onHide={close}>
<Modal.Header>
<Modal.Title>Title</Modal.Title>
</Modal.Header>
<Modal.Body>
'This is a body'
</Modal.Body>
<Modal.Footer>
<Button onClick={close} appearance="primary">
Save
</Button>
<Button onClick={close} appearance="subtle">
Cancel
</Button>
</Modal.Footer>
</Modal>
);
}
export default function Users() {
return (
<div>
<gridTable
....
rowFunc={
[name: 'deleteItem',
onClick: () => {
return (<setConfirmDelete state={modal} close={() => setModal(false)} />)
}
]
}>/<gridTable></div>)}
What I'm trying to do here is to display the modal when I click the function delete, I encounter the error which is the Property 'setConfirmDelete' does not exist on type 'JSX.IntrinsicElements' .
I also tried this code:
onClick={()=> setConfirmDelete({modal, false})
But it doesn't work or display the data
This particular error "Property 'setConfirmDelete' does not exist on type 'JSX.IntrinsicElements'" is because React assumes that all lower-case element names are built-in aka "intrinsic" elements. All of your components must use uppercase names like SetConfirmDelete.
You cannot return any JSX from an onClick. All event handler handler functions are void and should not return anything. You must instead set that JSX somewhere using state.
Let's change your modal state so that instead of true/false (show/hide) we either store the contents of the modal or false if there is no modal.
Let's make SetConfirmDelete into a valid React component that takes a close prop which is a function.
import React from "react";
import { Modal, Button } from "react-bootstrap";
interface ModalProps {
close: () => void;
// you'll want this is the future
onSubmit: () => void;
}
const ConfirmDeleteModal: React.FC<ModalProps> = ({ close, onSubmit }) => {
return (
<Modal show={true} onHide={close}>
<Modal.Header>
<Modal.Title>Title</Modal.Title>
</Modal.Header>
<Modal.Body>'This is a body'</Modal.Body>
<Modal.Footer>
<Button onClick={onSubmit} appearance="primary">
Save
</Button>
<Button onClick={close} appearance="subtle">
Cancel
</Button>
</Modal.Footer>
</Modal>
);
};
export default function Users() {
// modal state is either an element or false
const [modal, setModal] = React.useState<React.ReactElement | false>(false);
// helper function for setting modal to false
const close = () => setModal(false);
return (
<div>
<div>
<button
onClick={() =>
setModal(
<ConfirmDeleteModal
close={close}
onSubmit={() => console.log("executing delete")}
/>
)
}
>
Delete
</button>
</div>
{
// when the modal is an element, we display it
modal !== false && modal
}
</div>
);
}
Code Sandbox Link

I got infinity loop after creating one modal for all buttons

I have three buttons with different content and one modal, which I want to use after clicking on the button, and change the content. But after reloading my page, I got infinity loop in function, where I set true on view Modal. Can you help me, where is the issue?
First I created a state for my data and then I have functions, where I set state. And after a click on the button, I pass individual data (header, body) to showModal function with these data. But it is not working, I got infinity loop in showModal and I donĀ“t know why.
let header = null;
let body = null;
const [modal, setModal] = useState({
modalHeader: '',
modalBody: {},
modalStatus: false
});
const showModal = (header, body) => {
setModal({
modalHeader: header,
modalBody: body,
modalStatus: true
});
};
const hideModal = () => {
setModal({
modalHeader: '',
modalBody: null,
modalStatus: false
});
};
return(
<div>
<Modal
show={modal.modalStatus}
onCancel={hideModal}
header={modal.modalHeader}
footerClass="modalAction"
footer={
<React.Fragment>
<Button inverse onClick={hideModal}>
BACK
</Button>
</React.Fragment>
}>
<div className="backgroud-graph">
<h2 className="center">{modal.modalHeader}</h2>
<Pie data={modal.modalBody} />
</div>
</Modal>
<Button onClick={showModal(header="Cards" , body={dataYellowCardsCoop} )}>
Porovnanie kariet
</Button>
<Button onClick={showModal(header="Tackles" , body= {dataTacklesCoop})}>
Porovnanie obrannych zakrokov
</Button>
<Button onClick={showModal(header="Goals" , body= {dataGoalsCoop})}>
Porovnanie golov
</Button>
</div>
);
For the handler, you need to pass a function, not call it, as you do here:
onClick={showModal(header="Cards" , body={dataYellowCardsCoop} )}
In your case, when the component is rendered the showModal function is called.
Additionally, you pass arguments incorrectly (you don't need an equal sign and their names).
<Button onClick={() => showModal("Cards", {dataYellowCardsCoop})}>
Porovnanie kariet
</Button>

Calling a function from outside of Reactjs class

I am fairly new to Reactjs and am running into an issue. I am using Griddle to display my data and using a Custom Component as a Column Definition. This custom component is defined outside of the class that contains the Griddle render and contains two buttons - Delete and Edit. I need to be able to click on either button and launch a modal, which I am using React Modal for. If I put a button within the class I can launch the modal as expected, however, when I am trying to launch the modal from one of the Edit or Delete buttons it does not work and I get an error
Uncaught TypeError: M.handleOpenModal is not a function.
Here is the code for the component that uses the Griddle plugin:
const actionComponent = ({ value }) =>
<div>
<i className="fas fa-edit"></i> Edit
<i className="fas fa-times"></i> Delete
</div>
const handleModalOpen = function () {
LinersTable.handleOpenModal();
}
export default class LinersTable extends React.Component {
constructor(props) {
super(props);
this.state = { liners: [], station: '', loading: true, selectedRowId: 0 };
this.modalElement = React.createRef();
this.options = {
defaultSortName: 'title', // default sort column name
defaultSortOrder: 'desc' // default sort order
};
}
handleOpenModal() {
alert();
}
render() {
let contents = this.state.loading ? <p><em>Loading...</em></p> : this.renderLinersTable(this.state.liners);
return <div>
<button className='btn btn-primary' onClick={() => { this.refreshData() }}>Refresh</button>
<a href="LinerReads/Studio" className='btn btn-primary'>Studio View</a>
<a href="LinerReads/Add" className='btn btn-primary'>Add</a>
<LinersStations onChange={this.handleStationChange.bind(this)} />
<ModalWindow ref={this.modalElement} />
{contents}
</div>;
}
renderLinersTable(liners) {
return (
<Griddle
styleConfig={styleConfig}
data={liners}
plugins={[plugins.LocalPlugin]}
components={{ Layout: NewLayout }}>
<RowDefinition>
<ColumnDefinition id="title" title="Title" order={1} width={600} />
<ColumnDefinition id="startDateString" title="Start" order={2} width={200} />
<ColumnDefinition id="endDateString" title="End" order={3} width={200} />
<ColumnDefinition id="linerID" title="Actions" customComponent={actionComponent} width={200} />
</RowDefinition>
</Griddle>
)
}
}
I have tried moving the Custom Component inside the class
handleModalOpen = function () {
this.handleOpenModal();
}
handleOpenModal() {
alert();
}
but it then throws an error
ReferenceError: handleModalOpen is not defined
Uncaught (in promise) ReferenceError: handleModalOpen is not defined
Anyone have a suggestion as to what I am missing or doing incorrect?

React implement activity wheel while waiting on API call to return data

Just trying to return some data from the Magic the Gathering API (super fun game by the way). The api is a little slow to return data when I try to make a call to get some cards by searching for them.
I have a react bootstrap modal that pops up whenever I search a term. I'd like to render a spinner in it while I'm waiting to get the cards back, then remove it once some cards show up.
I was thinking that I could just display the spinner while my cards array was empty or undefined but since there's a pending promise representing the value I don't think that'll work?
Can someone help me out with the best way to do this?
state = {
modal: false,
form: "",
result: []
};
// function to get cards from the api and update the state
cardsLoaded = () => {
if (this.state.result === [] || this.state.result === undefined) {
return (
<Spinner animation="border" role="status">
<span className="sr-only">Loading...</span>
</Spinner>
);
} else {
return (
<div style={{ display: "block", width: "10em" }}>
{this.state.result.map((card, section, index, add) => {
return (
<div key={section} style={{ display: "inline" }}>
<button key={index}>{card}</button>
<button key={add} onClick={() => this.props.addToDeck(card)}>
<GiCardPlay />
</button>
</div>
);
})}
</div>
);
}
};
here is my modal where I am rendering the spinner:
<Modal
show={this.state.modal}
onExit={() => console.log("modal closed")}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>{() => this.cardsLoaded()}</Modal.Body>
<Modal.Footer>
<Button onClick={this.closeModal}>Close</Button>
</Modal.Footer>
</Modal>;
Is it possible for you to set a "loading" flag when you call your API and then clear it when your API call is resolved?
// set loading flag to true while fetching from API
this.setState({ loading: true });
// fetch from api, set flag to false once the api call resolves
// (whether it's successful or not)
fetch('http://apiuri.com/')
.then(res => {
// handle response here...
this.setState({ loading: false });
})
.catch(err => {
// handle error here...
this.setState({ loading: false });
})
Then where you are rendering your Spinner, you can render it conditionally with the loading flag.
this.state.loading && (
<Spinner animation="border" role="status">
<span className="sr-only">Loading...</span>
</Spinner>
)
You may have to shuffle some state/props around depending on your component hierarchy

How Can i display a Modal onSubmit Form?

I have a <Form> ( reduxForm ) Where user submits the values , as soon as the values got submitted It goes to another component showResults and that component Returns the Modal Component , Currently Modal Component is displays on the top of the App component ,
How Can I get the Modal component Popup once user have
submitted(pressed the submit button) the values and then using those
values Modal gets displayed accordingly
Form.jsx
<form onSubmit={handleSubmit}>
{allQuestions}
<div>
<button type="submit" disabled={pristine || submitting}>
Submit
</button> // Once your press this button Modal should PopuP
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
showResults.jsx
<Form
formData={formData}
onSubmit={e => {
this.onSubmit(e);
}}
/>
Modal.jsx
class ShowModal extends React.Component {
state = {
open: false,
};
onOpenModal = () => {
this.setState({ open: true });
};
onCloseModal = () => {
this.setState({ open: false });
};
render() {
const { open } = this.state;
return(
<Modal open={open} onClose={this.onCloseModal}>
<h4>Total : {this.props.total} Out of 10</h4>
</Modal>
</div>)
Either store the model open state outside of the component and use a property (proper way) or ref (the anti pattern way):
<ShowModal ref={(modal) => this.modal = modal} />
and later:
this.modal.setState(show:true)
but the proper property way would be:
<ShowModal open={this.sate.showModal} />
probably since you are using redux you want to store your modal open/close state in redux state as well

Categories