Search code examples
javascriptreactjsreduxreact-reduxdispatch

How to dispatch add and view functions inside same connect function in redux?


I'm using redux in my project. I have already completed getting data from the database and display them in the UI. Now what I want to do is add a create part in the same file. I can't think of a way how to dispatch it inside connect.For the instance in my action file I'm just console logging.If it logs I know how do the rest. Could you please help me to find a way to dispatch the create function? What I need to run is the this.props.addComments(this.state.commentText); inside handleClick() function.

ViewTicket.js

import React from 'react';
import TicketAction from './../../components/TicketTable/TicketAction/TicketAction';
import {
  ChevronLeft,
  Archive,
  ArrowClockwise,
  Share,
  Pencil
} from 'react-bootstrap-icons';
import Card from 'react-bootstrap/Card';
import { Row, Col } from 'reactstrap';
import { Tabs, Tab } from 'react-bootstrap';
import { connect } from 'react-redux';
import moment from 'moment';

import RichTextEditor from './../../components/EditorToolbar/RchTextEditor';
import PriorityBadge from './../../components/PriorityBadge/PriorityBadge';
import UserIcon from './../../components/UserIcon/UserIcon';
import { getTicketByID, addComments } from './actions/TicketActions';
import ActionButton from './../../components/ActionButton/ActionButton';

import './ViewTicket.scss';

class ViewTicket extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      editorText: 'This comes in the text editor',
      commentText: '',
      id: ''
    };
  }

  componentDidMount() {
    const { match } = this.props;
    let id = match.params.id;
    this.setState({
      id: match.params.id
    });
    this.props.getTicketByID(id);
  }

  displayComments = () => {
    if (this.props.comments[0] !== undefined) {
      return this.props.comments.map((item) => {
        return (
          <div>
            <Row style={{ marginBottom: 40 }}>
              <Col sm={1} className="user-avatar">
                <UserIcon name="Sam Smith" size="40" />
              </Col>
              <Col sm={7}>
                <div className="text p2">
                  <p2>Sam Smith</p2>
                </div>

                <div className="text p4">
                  <p4>{item.description}</p4>
                </div>
              </Col>
              <Col sm={4} className="comment-date-text text p4">
                <p4>December 27 ,2020,11.02 AM</p4>
              </Col>
            </Row>
            <div className="hr-line"></div>
          </div>
        );
      });
    }
  };

  handleChangeInputs = (event) => {
    this.setState({ commentText: event });
    console.log(this.state.commentText);
  };

  handleClick = () => {
    console.log('Handle Click');
    console.log(this.state.commentText);
    this.props.addComments(this.state.commentText);
  };

  render() {
    let {
      id,
      title,
      employer,
      description,
      assignee,
      status,
      priority,
      date
    } = this.props;

    // Change the date format
    date = moment(this.props.date).format('L');

    return (
      <div>
        <div className="icon-list">
          <TicketAction icon={<ChevronLeft />} tooltip="Back" />
          <TicketAction icon={<ArrowClockwise />} tooltip="Refresh" />
          <TicketAction icon={<Archive />} tooltip="Archive" />
          <TicketAction icon={<Share />} tooltip="E-mail" />
          <TicketAction icon={<Pencil />} tooltip="Edit" />
        </div>
        <div>
          <Card className="card">
            <Row>
              <Col sm={9}>
                <Card.Body>
                  <div className="header-date text p2">
                    <p2>2 DAYS AGO ON TUESDAY AT 5.43 AM</p2>
                  </div>

                  <Row>
                    <Col sm={3} className="title">
                      <h2>{title}</h2>
                    </Col>
                    <Col sm={7} className="drop-down">
                      <PriorityBadge priority="Error" />
                    </Col>
                    <Col sm={1}>
                      <Pencil />
                      &nbsp; Edit
                    </Col>
                  </Row>
                  <div className="ticket-data-topic text p3">
                    <p3>Hello,</p3>
                    <div className="ticket-data-content text p4">
                      <p4
                        dangerouslySetInnerHTML={{
                          __html: description
                        }}
                      ></p4>
                    </div>
                    <hr />
                    <br />
                    <Tabs>
                      <Tab eventKey={1} title="Comments">
                        <br />
                        <br />
                        {this.displayComments()}
                        <br />

                        <h3 className="add-comment-heading">Add Comment</h3>

                        <Row className="comments-section">
                          <div className="user-avatar-add-comments-section">
                            <UserIcon name="Shanil Silva" size="40" />
                          </div>
                          <Col sm={11}>
                            <RichTextEditor
                              editorStyle={'text-editor-view'}
                              value={this.state.commentText}
                              buttonText={'Add'}
                              onChange={this.handleChangeInputs}
                              onClick={this.handleClick}
                            />
                          </Col>
                        </Row>
                      </Tab>
                      <Tab
                        eventKey={2}
                        title="History"
                        className="nav-item nav-link active"
                      >
                        History
                      </Tab>
                    </Tabs>
                  </div>
                </Card.Body>
              </Col>
              <Col sm={1}>
                <div className="vl"></div>
              </Col>
              <Col sm={2} className="ticket-data-item-col">
                <Card.Body>
                  <div className=" ticket-item-title text p4">
                    <p>Created by</p>
                  </div>
                  <h4>John Doe ([email protected])</h4>
                  <p className="ticket-data-item">{date}</p>

                  <div className=" ticket-item-title text p4">
                    <p>Ticket ID</p>
                  </div>
                  <h4 className="ticket-data-item">{id}</h4>

                  <div className=" ticket-item-title text p4">
                    <p>Employer</p>
                  </div>
                  <h4 className="ticket-data-item">{employer}</h4>

                  <div className=" ticket-item-title text p4">
                    <p>Assigned to</p>
                  </div>
                  <h4 className="ticket-data-item">{assignee}</h4>

                  <div className=" ticket-item-title text p4">
                    <p>Status</p>
                  </div>
                  <h4 className="ticket-data-item">{status}</h4>

                  <div className=" ticket-item-title text p4">
                    <p>Priority</p>
                  </div>
                  <div className=" ticket-data-item-badge text p4">
                    <PriorityBadge priority={priority} />
                  </div>

                  <div className=" ticket-item-title text p4">
                    <p>Last Updated</p>
                  </div>
                  <h4>John Doe</h4>
                  <p>03/05/2020</p>
                </Card.Body>
              </Col>
            </Row>
          </Card>
        </div>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  let {
    id,
    title,
    employerId,
    description,
    assignee,
    ticketStatus,
    ticketPriority,
    ticketType,
    createdTs
  } = state.ViewTicketByID.ticketContent.data;

  let comments = state.ViewTicketByID.ticketContent.comments;

  return {
    id: id,
    title: title,
    employer: employerId,
    description: description,
    assignee: assignee,
    status: ticketStatus,
    priority: ticketPriority,
    type: ticketType,
    date: createdTs,
    comments
  };
};

const mapDispatchToProps = (dispatch, ownProps) => {
  let ticketID = ownProps.match.params.id;
  return {
    getTicketByID: () => dispatch(getTicketByID(ticketID))
  };
};

export default connect(
  mapStateToProps,mapDispatchToProps
)(ViewTicket);

TicketActions.js


import * as ActionTypes from '../actionTypes/ticketsActionTypes';
import TicketService from '../ViewTicketService';

export const getTicketByID = (id) => {
  return (dispatch) => {
    dispatch({ type: ActionTypes.GET_TICKET_BY_ID_IN_PROGRESS });
    TicketService.findTicketByID(id)
    .then((response)=>
    dispatch({
      type:ActionTypes.GET_TICKET_BY_ID_COMPLETED,
      payload:response
    })
    )
    .catch((error)=>
    dispatch({
      type:ActionTypes.GET_TICKET_BY_ID_FAILED,
      payload: error
    })
    )
  };
};

export const addComments = (commentData) => {
  return (dispatch) => {
    console.log('Ticket Actions add Comments');
    dispatch({ type: ActionTypes.GET_TICKET_BY_ID_IN_PROGRESS });
    // TicketService.findTicketByID(id)
    // .then((response)=>
    // dispatch({
    //   type:ActionTypes.GET_TICKET_BY_ID_COMPLETED,
    //   payload:response
    // })
    // )
    // .catch((error)=>
    // dispatch({
    //   type:ActionTypes.GET_TICKET_BY_ID_FAILED,
    //   payload: error
    // })
    // )
  };
};

Solution

  • I found the issue. You need to pass the function addComments in mapDispatchToProps. e.g.

    const mapDispatchToProps = (dispatch, ownProps) => {
      let ticketID = ownProps.match.params.id;
      return {
        getTicketByID: () => dispatch(getTicketByID(ticketID)),
        addComments
      };
    };