React SyncFusion Resource and grouping crud not binding the data in scheduler - reactjs

Add event is working(saving to database) but added events are not displaying on scheduler but its working with mocked data . Please let me know if any one know how to bind the data back on scheduler
Please click here to find the attachment image
Please see the above image response getting form api but not binding to scheduler UI
export class GroupEditing extends SampleBase {
constructor() {
super();
this.data = extend([], dataSource.resourceConferenceData, null, true);
this.state = {
customers: [],
technicians: [],
services: [],
groups: [],
};
this.currentEvent;
}
componentDidMount() {
axios
.post('URL', {
userId: '39',
companyId: '38',
dateTime: '2021-03-08 21:43:25',
roleId: 1,
})
.then((res) => {
const data = res.data.content[0];
this.setState({
customers: data.customer,
groups: data.group,
services: data.pestServices,
technicians: data.employee,
});
});
}
addTechnician(args) {
const { technicians } = this.state;
let row = createElement('div', { className: 'custom-field-row' });
let formElement = args.element.querySelector('.e-schedule-form');
const resource = formElement.querySelector('.e-resources-row');
resource.insertBefore(row, resource.firstChild);
let container = createElement('div', {
className: 'custom-field-container',
});
let inputEle = createElement('input', {
className: 'e-field e-input',
attrs: { name: 'employeeId', placeholder: 'Technicians' },
});
container.appendChild(inputEle);
row.appendChild(container);
let dropDownList = new DropDownList({
dataSource: technicians,
fields: { text: 'name', value: 'employeeId' },
value: args.data.Customers,
floatLabelType: 'Always',
placeholder: 'Technicians',
});
dropDownList.appendTo(inputEle);
inputEle.setAttribute('name', 'employeeId');
}
addCustomers(args) {
const { customers } = this.state;
let row = createElement('div', { className: 'custom-field-row' });
let formElement = args.element.querySelector('.e-schedule-form');
formElement.firstChild.insertBefore(row, formElement.firstChild.firstChild);
let container = createElement('div', {
className: 'custom-field-container',
});
let inputEle = createElement('input', {
className: 'e-field e-input',
attrs: { name: 'customerId', placeholder: 'Customers' },
});
container.appendChild(inputEle);
row.appendChild(container);
let dropDownList = new DropDownList({
dataSource: customers,
fields: { text: 'customerName', value: 'customerId' },
value: args.data.Customers,
floatLabelType: 'Always',
placeholder: 'Customers',
});
dropDownList.appendTo(inputEle);
inputEle.setAttribute('name', 'customerId');
}
onPopupOpen(args) {
if (args.type === 'Editor') {
if (!args.element.querySelector('.custom-field-row')) {
debugger;
this.addCustomers(args);
this.addTechnician(args);
}
}
}
render() {
const { services, groups, loading } = this.state;
return (
<div className='schedule-control-section'>
<div className='col-lg-12 control-section'>
<div className='control-wrapper'>
<ScheduleComponent
rowAutoHeight={true}
// popupOpen={this.onPopupOpen.bind(this)}
cssClass='group-editing'
width='100%'
height='650px'
selectedDate={new Date()}
// currentView='Day'
eventSettings={{
dataQuery: new Query().from('EventDatas'),
dataSource: new DataManager({
url: 'http://localhost:25255/api/Batch',
crossDomain: true,
adaptor: new UrlAdaptor(),
}),
}}
group={{
allowGroupEdit: false,
byGroupID: false,
resources: ['groupId', 'serviceId'],
}}
>
<ResourcesDirective>
<ResourceDirective
field='serviceId'
title='Services'
name='serviceId'
allowMultiple={true}
dataSource={services}
textField='serviceName'
idField='serviceId'
></ResourceDirective>
<ResourceDirective
field='groupId'
title='Group'
name='groupId'
allowMultiple={false}
dataSource={groups}
textField='name'
idField='groupId'
></ResourceDirective>
</ResourcesDirective>
<Inject
services={[
Day,
WorkWeek,
Month,
TimelineViews,
Resize,
DragAndDrop,
]}
/>
</ScheduleComponent>
</div>
</div>
</div>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

You have missed to add CrudUrl in the dataManager settings. So that the CRUD actions are not working. So we would suggest you to refer and follow the below sample.
Service: https://www.syncfusion.com/downloads/support/directtrac/general/ze/ScheduleCRUD-1748824462-1972500097
Sample: https://stackblitz.com/edit/react-schedule-url-adaptor-two-level-resource?file=index.js
this.dataManger = new DataManager({
url: 'http://localhost:54738/Home/LoadData',
crudUrl: 'http://localhost:54738/Home/UpdateData',
crossDomain: true,
adaptor: new UrlAdaptor
});
UG: https://ej2.syncfusion.com/react/documentation/schedule/data-binding/#scheduler-crud-actions

We could reproduce the reported issue “issue in deleting the entire recurrence events” and confirm this as defect at our end. You can keep track of the bug through the following feedback. The fix for this issue is expected to be rolled out in in our JS2 weekly release scheduled on April 27, 2021. We would appreciate your patience until then.
Feedback: https://www.syncfusion.com/feedback/24505/issue-in-deleting-the-entire-recurrence-events-with-resources-only-when-it-is

Related

Implementing Uppy.io StatusBar in react

I am trying to implement an Uppy.io statusbar upload as a react component. I tried using the wrapper but it does not work. If I use Dashboard or DragDrop then it does. Are there any tutorials or examples I could refer to ? My code looks like:
const UppyUpload = ({ uploadPayload }) => {
const uppy = useUppy(() => {
return new Uppy({
meta: { CaseId: '29670', CustomerId: '107', projectTitle: 'Trial' },
restrictions: { maxNumberOfFiles: 1 },
autoProceed: false,
})
.use(XHRUpload, {
endpoint: 'api/FormController/UploadVideo',
formData: true,
fieldName: 'Files',
})
.on('complete', (result) => {
const url = result.successful[0].uploadURL;
store.dispatch({
type: 'SET_USER_AVATAR_URL',
payload: { url },
});
});
});
return (
<div>
<StatusBar
uppy={uppy}
hideAfterFinish={false}
showProgressDetails
/>
</div>
);
};

calling setState from onClick JavaScript function not working

I am trying to create a button that will make visible a form to edit any contact on my list. However, when I press the button, nothing happens.
I have the initial state set to
this.state = {
contacts: [],
showEditWindow: false,
EditContactId: ''
};
I added a function:
editContact = (id) => {
this.setState({
showEditWindow: true, EditContactId: {id}
});
};
and a column:
{
title: "",
key: "action",
render: (record) => (
<button onClick={() => this.editContact(record.id)}
>
Edit
</button>
)
},
I imported EditContactModal and call it as
<EditContactModal reloadContacts={this.reloadContacts}
showEditWindow={this.state.showEditWindow}
EditContactId={this.state.EditContactId}/>
If I manually set this.state to showEditWindow:true, the window appears; however, either this.editContact(id) is not being called or it is not changing the state.
Calling this.deleteContact(id) works fine, as does setState in loadContacts() and reloadContacts()
What I am doing wrong?
Below are the full components.
Contacts.jsx
import { Table, message, Popconfirm } from "antd";
import React from "react";
import AddContactModal from "./AddContactModal";
import EditContactModal from "./EditContactModal";
class Contacts extends React.Component {
constructor(props) {
super(props);
this.state = {
contacts: [],
showEditWindow: false,
EditContactId: ''
};
this.editContact = this.editContact.bind(this);
};
columns = [
{
title: "First Name",
dataIndex: "firstname",
key: "firstname"
},
{
title: "Last Name",
dataIndex: "lastname",
key: "lastname"
},{
title: "Hebrew Name",
dataIndex: "hebrewname",
key: "hebrewname"
},{
title: "Kohen / Levi / Yisroel",
dataIndex: "kohenleviyisroel",
key: "kohenleviyisroel"
},{
title: "Frequent",
dataIndex: "frequent",
key: "frequent",
},{
title: "Do Not Bill",
dataIndex: "donotbill",
key: "donotbill"
},
{
title: "",
key: "action",
render: (record) => (
<button onClick={() => this.editContact(record.id)}
>
Edit
</button>
)
},
{
title: "",
key: "action",
render: (_text, record) => (
<Popconfirm
title="Are you sure you want to delete this contact?"
onConfirm={() => this.deleteContact(record.id)}
okText="Yes"
cancelText="No"
>
<a type="danger">
Delete{" "}
</a>
</Popconfirm>
),
},
];
componentDidMount = () => {
this.loadContacts();
}
loadContacts = () => {
const url = "http://localhost:3000/contacts";
fetch(url)
.then((data) => {
if (data.ok) {
return data.json();
}
throw new Error("Network error.");
})
.then((data) => {
data.forEach((contact) => {
const newEl = {
key: contact.id,
id: contact.id,
firstname: contact.firstname,
lastname: contact.lastname,
hebrewname: contact.hebrewname,
kohenleviyisroel: contact.kohenleviyisroel,
frequent: contact.frequent.toString(),
donotbill: contact.donotbill.toString(),
};
this.setState((prevState) => ({
contacts: [...prevState.contacts, newEl],
}));
});
})
.catch((err) => message.error("Error: " + err));
};
reloadContacts = () => {
this.setState({ contacts: [] });
this.loadContacts();
};
deleteContact = (id) => {
const url = `http://localhost:3000/contacts/${id}`;
fetch(url, {
method: "delete",
})
.then((data) => {
if (data.ok) {
this.reloadContacts();
return data.json();
}
throw new Error("Network error.");
})
.catch((err) => message.error("Error: " + err));
};
editContact = (id) => {
this.setState({
showEditWindow: true, EditContactId: {id}
});
};
render = () => {
return (
<>
<Table
className="table-striped-rows"
dataSource={this.state.contacts}
columns={this.columns}
pagination={{ pageSize: this.pageSize }}
/>
<AddContactModal reloadContacts={this.reloadContacts} />
<EditContactModal reloadContacts={this.reloadContacts}
showEditWindow={this.state.showEditWindow}
EditContactId={this.state.EditContactId}/>
</>
);
}
}
export default Contacts;
EditContactModal.jsx
import { Button, Form, Input, Modal, Select } from "antd";
import React from "react";
import ContactForm from './ContactForm';
const { Option } = Select;
class EditContactModal extends React.Component {
formRef = React.createRef();
state = {
visible: this.props.showEditWindow,
};
onFinish = (values) => {
const url = `http://localhost:3000/contacts/${this.props.EditContactId}`;
fetch(url, {
method: "put",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(values),
})
.then((data) => {
if(data.ok) {
this.handleCancel();
return data.json();
}
throw new Error("Network error.");
})
.then(() => {
this.props.reloadContacts();
})
.catch((err) => console.error("Error: " + err))
};
showModal = () => {
this.setState({
visible: true,
});
};
handleCancel = () => {
this.setState({
visible: false,
});
};
render() {
return (
<>
{/*<Button type="primary" onClick={this.showModal}>
Create New +
</Button>*/}
<Modal
title="Edit Contact"
visible={this.state.visible}
onCancel={this.handleCancel}
footer={null}
>
<ContactForm />
</Modal>
</>
);
}
}
export default EditContactModal;
if your aim is to perform an update to the state object, you must not pass mutable data, but copy it instead into a new object.
this will allow the state changes to be picked up.
so, prefer setState({ ...state, ...someObject }) over setState(someObject).

Checkbox value in React and MongoDB

What I am seeking to accomplish is to have an optional checkbox in a form that returns false when unchecked and true when checked (in the DB).
However, whenever I view my submission in the console, things appear to be find - just not showing up in Mongo. I have attempted numerous things after searching all day both frontend and backend schema. Any help or insight would be much appreciated.
export default class CreateworkOrder extends Component {
constructor(props) {
super(props);
this.onChangeEmployee = this.onChangeEmployee.bind(this);
this.onChangeDescription = this.onChangeDescription.bind(this);
this.onChangeDuration = this.onChangeDuration.bind(this);
this.onChangeDate = this.onChangeDate.bind(this);
this.handleCheckClick = this.handleCheckClick.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
employee: '',
description: '',
duration: 0,
date: new Date(),
employees: [],
isComplete: false
}
}
componentDidMount() {
axios.get('http://localhost:5000/employees/')
.then(response => {
if (response.data.length > 0) {
this.setState({
employees: response.data.map(emp => emp.employee),
employee: response.data[0].employee
})
}
})
.catch((error) => {
console.log(error);
})
}
handleCheckClick = () => {
const complete = !this.state.isComplete;
console.log(complete);
this.setState({ complete: !this.state.isComplete});
}
Then submit below:
onSubmit(e) {
e.preventDefault();
const workOrder = {
employee: this.state.employee,
description: this.state.description,
duration: this.state.duration,
date: this.state.date,
isComplete: this.state.isComplete
}
console.log(workOrder);
axios.post('http://localhost:5000/workOrders/add', workOrder)
.then(res => console.log(res.data)).catch(console.error);
//window.location = '/home';
}
portion of the form to optionally select
<div className="form-group">
<label>Only check box if job has been completed </label>
<input name="isComplete" type="checkbox"
defaultChecked={this.state.isComplete}
onChange={this.handleCheckClick}
className="filled-in" id="filled-in-box"/>
</div>
<div className="form-group">
<input type="submit" value="Create WO" className="btn btn-primary" onSubmit={this.onSubmit}/>
</div>
</form>
DB Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const workorderSchema = new Schema({
employee: { type: String, required: true },
description: { type: String, required: true },
duration: { type: Number, required: true },
date: { type: Date, required: true },
isComplete: { type: Boolean, required: false },
},
{
timestamps: true,
});
const WorkOrder = mongoose.model('WorkOrder', workorderSchema);
module.exports = WorkOrder;
but console does show true
You are using the state variable isComplete but setting the state in complete.
this.state = {
employee: '',
description: '',
duration: 0,
date: new Date(),
employees: [],
isComplete: false
}
In handleCheckClick you are doing:
handleCheckClick = () => {
const complete = !this.state.isComplete;
console.log(complete);
this.setState({ complete: !this.state.isComplete}); }
And you are submitting workOrder which is using isComplete, which you didn't change
const workOrder = { employee: this.state.employee, description:
this.state.description, duration: this.state.duration, date:
this.state.date, isComplete: this.state.isComplete }
This should be the reason. So change the handleCheckClick like this:
handleCheckClick = () => {
let complete = !this.state.isComplete;
console.log(complete);
this.setState({ isComplete: complete});
}
Also, I noticed that you are using const keyword and then trying to change its value. const means the value shouldn't change. Use either let or var in future if you want a variable to be mutable

Getting error while showing hiding React Table columns - React JS

I am working on React Table. I am basically a beginner in React. I have a dashboard page where I display a React Table of 8 columns. I have a customize button which will open a popup page, this popup page has 8 check boxes allows me to show/hide those React columns. Initially all the check boxes in this popup page is set to true. When I uncheck a column that particular column get disabled.
There are images in the end to see what I am trying to do.
I will be using this logic for show hide columns (this question was asked by me two days back) -
How to show and hide some columns on React Table?
The React Table data is like this
const columns = [
{
Header: 'Column 1',
accessor: 'firstName',
},
{
Header: 'Column 2',
accessor: 'firstName',
},
{
Header: 'Column 3',
accessor: 'firstName',
},
{
Header: 'Column 4',
accessor: 'firstName',
},
{
Header: 'Column 5',
accessor: 'firstName',
},
{
Header: 'Column 6',
accessor: 'firstName',
},
{
Header: 'Column 7',
accessor: 'firstName'
},
{
Header: 'Column 8',
accessor: 'firstName',
}
];
The start of the dashboard page
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
filterState: {},
searchText: '',
isFilterOpen: false,
isCustomizedOpen: false,
isFiltered: false,
isSearched: false,
searchedTableData: [],
filteredTableData: [],
};
this.handleCustClickinv = this.handleCustClickinv.bind(this);
}
This is my code in the render function of my dashboard page for showing the customize button (this is written in parent dashboard page)
{this.state.isCustomizedOpen && <CustomizedView
filterState={this.state.filterState}
applyFilter={(values, clear) => { this.applyFilters(values, clear); }}
/>}
This is the code for the customize button (this is written in parent dashboard page)
<div className="custom-div-dashboard" onClick={() => { this.handleCustClickinv(); }}>
<div className='customize-view-dashboard'>Customized View </div>
</div>
This is function to handle the click on customize button (this is written in parent dashboard page)
handleFilterClickinv() {
if(this.state.isCustomizedOpen) {
this.setState({ isCustomizedOpen: false });
}
const currentState = this.state.isFilterOpen;
this.setState({ isFilterOpen: !currentState });
}
This is my entire popup page which will have 8 check boxes
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { ActionCreators } from '../../../actions';
import './enqCustomizedView.scss';
import ButtonComponent from '../../shared/button/ButtonComponent';
import { CheckBox } from '../../shared/chkbox/CheckBox';
class CustomizedView extends Component {
constructor(props) {
super(props);
this.state = {
items: [
{ id: 1, value: 'Column 1', isChecked: true },
{ id: 2, value: 'Column 2', isChecked: true },
{ id: 3, value: 'Column 3', isChecked: true },
{ id: 4, value: 'Column 4', isChecked: true },
{ id: 5, value: 'Column 5', isChecked: true },
{ id: 6, value: 'Column 6', isChecked: true },
{ id: 7, value: 'Column 7', isChecked: true },
{ id: 8, value: 'Column 8', isChecked: true },
]
};
this.handleCheckChildElement = this.handleCheckChildElement.bind(this);
}
handleClick() {
this.setState({ isChecked: !this.state.isChecked });
}
handleCheckChildElement(event) {
//let items = this.state.items;
let { items } = this.state;
items.forEach(items = () => {
if(items.value === event.target.value) {
items.isChecked = event.target.checked;
}
});
this.setState({ items });
const column1checked = items[0].isChecked;
console.log('column1checked ' + column1checked);
const column2checked = items[1].isChecked;
console.log('column2checked ' + column2checked);
const column3checked = items[2].isChecked;
console.log('column3checked ' + column3checked);
const column4checked = items[3].isChecked;
console.log('column4checked ' + column4checked);
const column5checked = items[4].isChecked;
console.log('column5checked ' + column5checked);
const column6checked = items[5].isChecked;
console.log('column6checked ' + column6checked);
const column7checked = items[6].isChecked;
console.log('column7checked ' + column7checked);
const column8checked = items[7].isChecked;
console.log('column8checked ' + column8checked);
}
render() {
return (
<div className='popup-page-custom' >
<div className='bottomBar'>
<ButtonComponent
text='Apply'
className='activeButton filterMargin'
width='100'
display='inline-block'
onClick={() => { this.props.applyFilter(this.state, false); }}
/>
<ButtonComponent
text='Clear Filter'
className='greyedButton clear-filter'
width='100'
display='block'
marginTop='60'
onClick={() => { this.props.applyFilter(this.state, true); }}
/>
</div>
<div>
<div className='data-points-text'>
<span> Columns </span>
</div>
<div className="App">
<ul>
{
this.state.items.map((item, i) => {
return (<div key={i} ><CheckBox handleCheckChildElement={this.handleCheckChildElement} {...item} /></div>);
})
}
</ul>
</div>
</div>
</div>
);
}
}
CustomizedView.propTypes = {
applyFilter: PropTypes.func.isRequired
};
CustomizedView.defaultProps = {
};
function mapStateToProps(state) {
return {
auth: state.auth
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(CustomizedView);
And ultimately this is my checkbox page
import React from 'react';
import PropTypes from 'prop-types';
export const CheckBox = (props) => {
// super(props);
return (
<li>
<input key={props.id} onClick={props.handleCheckChildElement} type="checkbox" checked={props.isChecked} value={props.value} /> {props.value}
</li>
);
};
CheckBox.propTypes = {
id: PropTypes.string,
handleCheckChildElement: PropTypes.func,
isChecked: PropTypes.bool,
value: PropTypes.string,
};
CheckBox.defaultProps = {
id: '',
handleCheckChildElement: null,
isChecked: null,
value: '',
};
export default CheckBox;
This is a very basic (ugly) style of my dashboard page and popup page
This is the error I am getting on Chrome when unchecking the checkboxes
Edit 1 - As per Alireza Yadegari's suggestion, I made a 1 line change. But I am still getting 2 errors.
Edit 2 - As per Alireza Yadegari's suggestion, I applied console.
you have to use this piece of code in your constructor
this.handleCheckChildElement = this.handleCheckChildElement.bind(this)
let { items } = { ...this.state };
this is wrong ....
firstly you destructuring array to object then saying give me items prop from given object... of course this is wrong
const { items} = this.state;
takes items prop from the state
and finally.... implement your task with foreach is bad idea...
CheckBox.defaultProps = {
id: '',
handleCheckChildElement: null,
isChecked: null, value: '',
};
i don't understand what it does. you know?
I think your project is a sample and no need for further examples.
I just say about your mistakes.
first, when you are using methods it is good to use 'bind(this)' to show react where is the method belongs.
secondly, when you are using state, react just allows you to change it in the constructor and wherever you want to change it you have to use 'setState' method (you can read the reason for this in react documentation).
finally, if you have an array in your state you have to get an array in some temp object change the temp object and then apply changes with 'setState' method. if you have more question please feel free to ask.

React ChartJS prevent new data from being added into state after it's redrawn?

I'm trying to update my chart using react-chartjs-2. I'm using date picker to filter different data and re-render the chart accordingly such as display data today, yesterday, last 7 days etc.. The data is being fetched from my database
However, when the chart gets redrawn, and re-rendered, it gets added onto the state which I don't want. I simply want to re-render the new data that was requested not re-render and add onto the old data that was in the chart.
I actually fixed this issue before with vanilla JavaScript because I wasn't using react I used the destroy() method that the chart documentation says to use but i'm not sure how to use it with react?
So upon further inspection, it seems my chart is re-rendering fine. However, when it gets re-rendered, additional data is being added onto my chartData state which I don't want, I just want the new data that got requested to show on the chart. I'm still trying to figure that portion out.
Here is my code I have a lot of it so I'll only show the relevant parts:
import React from "react";
import reportsService from "../../services/reportsService";
import update from "react-addons-update";
import moment from "moment";
import { Bar } from "react-chartjs-2";
import "chartjs-plugin-labels";
import "chartjs-plugin-datalabels";
class Reportspage extends React.Component {
constructor(props) {
super(props);
this.state = {
chartData: {
labels: [],
datasets: [
{
//label: "Quotes",
data: [],
backgroundColor: []
}
]
}
};
}
chartColors() {
let colors = [];
for (let i = 0; i < 100; i++) {
let r = Math.floor(Math.random() * 200);
let g = Math.floor(Math.random() * 200);
let b = Math.floor(Math.random() * 200);
let c = "rgb(" + r + ", " + g + ", " + b + ")";
colors.push(c);
}
// Update deep nested array of objects in state
this.setState({
chartData: update(this.state.chartData, {
datasets: { 0: { backgroundColor: { $set: colors } } }
})
});
}
datePicker() {
let _this = this;
let start = moment().subtract(29, "days");
let end = moment();
let showReports;
let data;
let reloNames = [];
let reloCount = [];
function focusDate(start, end) {
$("#daterangePicker span").html(
start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY")
);
}
$("#daterangePicker").daterangepicker(
{
startDate: start,
endDate: end,
ranges: {
Today: [moment(), moment()],
Yesterday: [
moment().subtract(1, "days"),
moment().subtract(1, "days")
],
"Last 7 Days": [moment().subtract(6, "days"), moment()],
"Last 30 Days": [moment().subtract(29, "days"), moment()],
"This Month": [moment().startOf("month"), moment().endOf("month")],
"Last Month": [
moment()
.subtract(1, "month")
.startOf("month"),
moment()
.subtract(1, "month")
.endOf("month")
]
}
},
focusDate
);
focusDate(start, end);
$("#daterangePicker").on("apply.daterangepicker", async function(
event,
picker
) {
switch (picker.chosenLabel) {
case "Today":
showReports = await reportsService.reloQuotes({
reportStatus: "Today"
});
data = showReports.recordsets[0];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
_this.setState({
chartData: update(_this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
console.log(_this.state);
break;
case "Yesterday":
showReports = await reportsService.reloQuotes({
reportStatus: "Yesterday"
});
data = showReports.recordsets[0];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
_this.setState({
chartData: update(_this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
console.log(_this.state);
break;
case "Last 7 Days":
showReports = await reportsService.reloQuotes({
reportStatus: "Last 7 Days"
});
data = showReports.recordsets[0];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
_this.setState({
chartData: update(_this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
console.log(_this.state);
break;
}
});
//console.log(this.state);
}
async reloQuotes() {
const showreloQuotes = await reportsService.reloQuotes();
let data = showreloQuotes.recordsets[0];
let reloNames = [];
let reloCount = [];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
this.setState({
chartData: update(this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
}
async componentDidMount() {
await this.chartColors();
await this.datePicker();
// Execute models real time thus re-rendering live data on the chart real time
await this.reloQuotes();
}
render() {
return (
<div className="fluid-container">
<div className="container">
<h1>Reports</h1>
<div className="row">
<div className="daterangeContainer">
<div
id="daterangePicker"
style={{
background: "#fff",
cursor: "pointer",
padding: "5px 10px",
border: "1px solid #ccc",
width: "100%"
}}
>
<i className="fa fa-calendar" />
<span /> <i className="fa fa-caret-down" />
</div>
</div>
</div>
<div className="row">
<div className="col-md-12">
<Bar
data={this.state.chartData}
height={800}
options={{
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [
{
ticks: {
beginAtZero: true,
autoSkip: false
},
scaleLabel: {
display: true
}
}
]
},
title: {
display: true,
text: "Quotes",
fontSize: 16
},
plugins: {
datalabels: {
display: true,
color: "white"
}
}
}}
redraw
/>
</div>
</div>
</div>
</div>
);
}
}
export default Reportspage;
So the problem that you describe is that data is added to your component state when the component is re-rendered. In the code snipped you have supplied, you dont use any of the life cycle methods in React that can be triggered on re-renders. And I cannot see any other hooks that should trigger on a re-render. Therefore I cant find any source to your problem.
However, I can see other issues that might make debugging harder for you. Solving these might help you in nailing down the actual problem. In the componentDidMount method you call functions whose only purpose is to update the state. This is not good design since it will force the component to immediately re-render several times whenever it is mounted.
A better design is to fully prepare the chartData-objekt in the constructor. For example, you could change your chartColors function to take a chartData object as a parameter, and return the new object with colors added. Then make your constructor look something like this:
constructor(props) {
super(props);
const chartDataWithoutColors = {
labels: [],
datasets: [
{
//label: "Quotes",
data: [],
backgroundColor: []
}
]
}
const chartDataWithColor = this.chartColors(chartDataWithoutColors);
this.state = {
chartData: chartDataWithColor
};
}
By removing unnecessary calls to setState you will make your components life both simpler and more performant. When you have simplified your component, start debugging by removing non-critical parts one at the time and try to nail down when your problem disappears. This should be sufficient to find the bug.
Good luck!

Resources