Reputation: 383
I am trying to pass the id from my React app to axios.get on the server side (Express) so I get this:
//get
app.get('/api/siteDashboard', (req, res, next) => {
axios.get('https://****/api/site?id=3d5a6a8a-60d4-4488-1401-08d74bf02cbf')
.then(response => res.json(response.data))
.catch(err => next(err));
})
On the client side I have a datatable and each row has a link to a new page. The data for the datatable is coming from the api. I want to be able to click the link for a specific row and grab its ID from the api and open the new page based on this ID.
<Link to="/Sites/SiteDashboard">
<MDBIcon icon="fa fa-external-link-alt" size="lg" className='green-text cursor-pointer' />
</Link>
I am fetching the route from the server like this in my client side React app..
componentDidMount() {
this.setState({ loading: true });
//const { match: { params }} =this.props
//fetch(`/api/site/?id=${this.state.siteDashboard}`)
fetch(`/api/siteDashboard`)
.then(res => res.json())
.then(data => {
this.setState({
siteData: data,
loading: false,
})
})
So basically, rather than hard coding the id into the axios.get request, I need to dynamically grab this from the link on the client side. Im not sure if I am approaching this the right way so any advice appreciated. Thanks.
React code...
import React from 'react'
import { Redirect } from "react-router-dom";
import styled from 'styled-components';
import DataTable, { memoize } from 'react-data-table-component'
import Moment from 'react-moment';
import Spinner from '../../Spinner'
import { BrowserRouter as Route, Link } from "react-router-dom";
import { MDBContainer, MDBCard, MDBCardBody, MDBRow, MDBCol, MDBBtn, MDBIcon } from 'mdbreact';
//import SiteDashboard from './SiteDashboard';
import SiteAdd from './SiteAdd'
import SiteDashboard from './SiteDashboard'
const TextField = styled.input`
height: 32px;
width: 300px;
border-radius: 3px;
border: 1px solid #e5e5e5;
padding: 16px;
&:hover {
cursor: pointer;
}
`;
const Filter = ({ onFilter }) => (
<TextField id="search" type="search" role="search" placeholder="Search Title" onChange={e => onFilter(e.target.value)} />
);
const columns = memoize(clickHandler => [
{
name: 'Online',
selector: 'cloudAccessEnabled',
sortable: true,
minWidth: '10px',
center: true,
cell: row => (
<MDBIcon icon="circle"
className={row.cloudAccessEnabled === true ? 'green-text' : 'red-text'} />
)
},
{
name: 'Site Ref.',
selector: 'siteRef',
sortable: true,
wrap: true,
minWidth: '40px',
},
{
name: 'Name',
selector: 'name',
sortable: true,
wrap: true,
minWidth: '80px',
},
{
name: 'Address Type',
sortable: true,
wrap: true,
minWidth: '100px',
//dont show this column
hide: 6000,
cell: row => (
<div>
{row.addresses && row.addresses.map(
({ addressType, id }) => (
<div key={id}>
<ul>
<li>{addressType}</li>
</ul>
</div>
))}
</div>
)
},
{
name: 'Address',
selector: 'address',
wrap: true,
minWidth: '100px',
cell: row => (
<div>
{row.addresses && row.addresses.map(
({ addressType, address1, address2, city, county, postCode, country, id }) => (
<div key={id}>
<ul>
<li><strong>{addressType}</strong></li>
<li>{address1}</li>
<li>{address2}</li>
<li>{city}</li>
<li>{county}</li>
<li>{postCode}</li>
<li>{country}</li>
</ul>
</div>
))}
</div>
)
},
{
name: 'Control Panel',
selector: 'controlPanel',
minWidth: '70px',
wrap: true,
cell: row => (
<div>
{(row.controlpanel == null) ?
<div>no CP assigned</div> : row.controlpanel}
</div>
)
},
{
name: 'Last Maintenance',
selector: 'lastMaintenance',
defaultSortAsc: true,
sortable: true,
wrap: true,
minWidth: '100px',
//hide: 1030,
cell: row => (
<Moment format="DD/MM/YYYY HH:mm">{row.lastMaintenance}</Moment>
)
},
{
name: 'Next Maintenance',
selector: 'nextMaintenance',
sortable: true,
wrap: true,
minWidth: '100px',
//hide: 1030,
cell: row => (
<Moment format="DD/MM/YYYY HH:mm">{row.nextMaintenance}</Moment>
)
},
{
name: 'Latest Result',
selector: 'latestResult',
sortable: true,
minWidth: '90px',
},
{
name: 'Site Dashboard',
minWidth: '47px',
center: true,
cell: row => (
<MDBIcon onClick={clickHandler} icon="fa fa-external-link-alt" size="lg" className='green-text cursor-pointer' />
)
},
]);
class Sites extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
sites: [],
toggledClearRows: false
}
}
// handler for link to Site Dashboard
handleButtonClick = () => {
console.log("clicked");
//<Redirect to={"/Sites/SiteDashboard" + this.state.sites.id} />
};
componentDidMount() {
this.setState({ loading: true });
//const { match: { params } } =this.props
fetch('/api/site')
.then(res => res.json())
.then(site => {
this.setState({
sites: site.array,
//cahnge to true to debug
loading: false
});
console.log(this.state.sites)
})
.catch(error => {
if (error.response) {
console.log(error.responderEnd);
}
});
}
render() {
// The row data is composed into your custom expandable component via the data prop
const ExpandedSection = ({ data }) =>
<MDBContainer fluid>
<p className="small mt-2">
<strong>Notes: </strong>
{data.notes}
</p>
</MDBContainer>
//Spinner
const CustomLoader = () => (<div><Spinner /></div>);
const { loading } = this.state;
return (
<div>
<MDBCard className="full-width sites-dt">
<MDBCardBody>
<MDBRow className="my-4 ml-1">
<MDBCol sm="12" md="4" className="text-center text-md-left">
<h3>Sites</h3>
</MDBCol>
<MDBCol sm="12" md="8" className="text-center text-md-right">
<Route path="/Sites/SiteAdd" component={SiteAdd} />
<Link to={`/Sites/SiteAdd`}>
<MDBBtn outline color="primary">
<MDBIcon icon="plus" /> Add a new Site
</MDBBtn>
</Link>
</MDBCol>
</MDBRow>
<Link to={`/Sites/SiteDashboard`}>temp link to Site Dashboard <MDBIcon icon="fa fa-external-link-alt" size="lg" className='green-text' />
</Link>
<MDBRow>
<MDBCol>
<DataTable className="responsive-table site-headers pagination-align-left"
columns={columns(this.handleButtonClick)}
data={this.state.sites}
defaultSortField="siteRef"
defaultSortAsc={false}
subHeader
//subHeaderComponent={<Filter onFilter={value => setFilterText(value)} />}
compact
pagination
highlightOnHover
expandableRows
expandableRowsComponent={<ExpandedSection />}
progressPending={loading}
progressComponent={<CustomLoader />}
/>
</MDBCol>
</MDBRow>
</MDBCardBody>
</MDBCard>
</div>
);
}
}
export default Sites
Upvotes: 0
Views: 9918
Reputation: 393
you can a write a separate function for the API call from where you are getting ids/routes:
ComponentDidMount(){
app.get('/api/siteDashboard', (req, res, next) => {
// your call
})
}
Here you have to make a change in route as well to add another route on the client-side, so to make URL for every item in the table.
<Route path='/site/siteDashboard/:id' component={youComponent} />
//youComponent which shows the details of the item
and where you are mapping your items in the table, just wrap each item with
<Link to=`/sites/siteDashboard/${this.state.id} />
Now when on the component where you are showing item details :
var id = props.match.params.id; // this will get your id from URL
or
var id = this.props.match.params.id;
axios.get('https://pathc/id?=${id}') //like this
and pass it to the API call to get its data.
Upvotes: 2
Reputation: 7414
Can you share the React code also? Will edit my answer with appropriate code
What you need to do is:
id
prop, sending an axios request to fetch the dataUpvotes: 0