Desmoline Awa
Desmoline Awa

Reputation: 535

When does mapStateToProps occur in the component life cycle

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: &nbsp;
              <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

Answers (1)

CharlieBrown
CharlieBrown

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

Related Questions