Reputation: 535
I have a list of items in table. I want to be able to click on a details
link on any item and go to a new page where I see the details of the item. Below is my code.
import React from 'react';
import { connect } from 'react-redux';
import toastr from 'toastr';
import { Link } from 'react-router';
import { bindActionCreators } from 'redux';
import * as documentActions from '../../actions/documentActions';
class DocumentDetailsPage extends React.Component {
constructor(props) {
super(props);
this.deleteDoc = this.deleteDoc.bind(this);
}
deleteDoc(id) {
this.props.actions.deleteDocument(id)
.then(res => toastr.success('Document deleted successfully!'));
}
render() {
const { document } = this.props;
return (
<div className="col s12">
<div className="card qBox">
<div className="card-content white-text">
<span className="card-title">{document.title}</span>
<p
dangerouslySetInnerHTML={{ __html: document.content }}
className="document-content"></p>
<br />
<p>Access Type:
<span>{(document.access).toUpperCase()}</span></p><br />
<div>
Published Date :
<p>{(document.createdAt) ?
document.createdAt.split('T')[0] : ''}</p>
<p id="owner">Author:
{document.owner.firstName} {document.owner.lastName}</p>
</div>
</div>
<div className="card-action">
<Link to="/">back</Link>
{this.props.auth.user.userId === document.ownerId &&
<div className="right">
<Link to={`/document/${document.id}`}>Edit</Link>
<Link to="/" onClick={this.deleteDoc()}> Delete </Link>
</div>
}
</div>
</div>
</div>
);
}
}
DocumentDetailsPage.propTypes = {
document: React.PropTypes.object.isRequired,
actions: React.PropTypes.object.isRequired,
auth: React.PropTypes.object.isRequired,
};
function getDocumentById(documents, id) {
const document = documents.filter(item => item.id === id);
if (document) return document[0];
return null;
}
function mapStateToProps(state, ownProps) {
const documentId = ownProps.params.id; // from the path `/document/:id`
let document;
if (documentId && state.documents.length > 0) {
document = getDocumentById(state.documents, parseInt(documentId, 10));
}
return {
document,
auth: state.auth,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(documentActions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(DocumentDetailsPage);
When I click on the details
link, it should take me to this page with route document/:id
where I can read the id
from the route and fetch the corresponding document from state and render in the component. But when i go to this page, it tells me that document
is undefined. Any reason for this? or is there a better way to get the param id
from the route than using mapStateToProps
?
Upvotes: 1
Views: 876
Reputation: 4163
You have two problems here:
1) Your deleteDoc
class method expects an id
argument which is passed to your action creator. Because you already have the full document as a prop, get it from the object instead of receiving it:
deleteDoc() {
const { actions, document } = this.props
actions.deleteDocument(document.id)
.then(res => toastr.success('Document deleted successfully!'));
}
2) You're CALLING the deleteDoc
function in your onClick
handler!
// Wrong
<Link to="/" onClick={this.deleteDoc()}> Delete </Link>
Remove the parens and simply set a reference to your function as the onClick
prop, not the result from an actual call. :)
// Right
<Link to="/" onClick={this.deleteDoc}> Delete </Link>
Upvotes: 1