Link to home
Start Free TrialLog in
Avatar of roger v
roger vFlag for United States of America

asked on

Need help with react/redux app - spinning loader not working

ReactReduxCodeFile.rtfI'm a total react/redux newbie; I have a react/redux app that loads a page based on 2 sets of select boxes; When user makes selection, the dispatch event happens and immediately a spinning loader icon is displayed which displays until all the data is loaded. Somewhere in the attached file code, that part is not working. Any help is appreciated.
Avatar of leakim971
leakim971
Flag of Guadeloupe image

please post the code
Avatar of roger v

ASKER

no need to upload, just copy paste here the code, select all and click on the CODE style button
Avatar of roger v

ASKER

import React,  { Component } from 'react';
import { connect } from 'react-redux';
import Table from '@material-ui/core/Table';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import {  Route, Link } from 'react-router-dom';
import {CSVLink} from 'react-csv';


import Header from '../components/header';
import Navbar from '../components/navbar';
import ReportDetails from '../components/rptComponents/reportDetails'
import TableHeaders from '../components/reports/tableHeaders'
import TableContent from '../components/reports/tableContent'
import { CircularProgress, FormControl, Input, InputLabel } from '@material-ui/core';
import GetAppIcon from '@material-ui/icons/GetApp';
import { ReportGetAllChannels, ReportGetAllPackages } from "../redux/actions/reportsActions/ReportsActions";
import { idlePeriod } from '@polymer/polymer/lib/utils/async';
import '../css/reports.less'
import '../css/home.less';

function toKey(s) {
	return s.split("_").map((s, i) => i > 0 ? s.slice(0,1).toUpperCase() + s.slice(1, s.length) : s).join("")
  }


function toLabel(s) {
	return s.split("_").map((s, i) => s.slice(0,1).toUpperCase() + s.slice(1, s.length)).join(" ")
  }


class Reports extends Component {
	constructor(props) {
		super(props);

		this.state = {
			report: '',
			filename: 'my-data.csv',
			isLoading: false,
			tableHeaderData: [],
			reports: [
				{ name: 'C3 Report', id: 1, actOn: 'c3'},
				{ name: 'C4 Report', id: 2, actOn: 'c4'},
				{ name: 'C5 Report', id: 3, actOn: 'c5'}
			],
			categories: {name: 'Cat 1'},
			catSelection: 'Select a Category',
			repSelection: 'Select Report Type',
			isReportSelected: false,
			c4RptFirstInput: '',
			c4RptSecondInput: ''
		}

	}

	componentDidMount () {
		const {dispatch, id} = this.props;

	}

	handleChange (e) {
		// this.setState({ input: e.target.value });
	}

	csvHeader () {

		const  data = this.reportData()
		if(data.length === 0) return []
		const keys = Object.keys(data[0])
		return keys.map((k) => {
			const label  = toLabel(k)
			const key = toKey(k)
			return { label, key }
		})
		
	}

	
	csvData () {

		const  data = this.reportData()
		if(data.length === 0) return []
		const values = Object.entries(data);
		
		const keys = Object.keys(data[0])

		const rows = values.map(entries => {
			const record = entries[1];
			return keys.reduce((acc, key, i) => {
				acc[toKey(key)] = record[key]
				return acc
			}, {})

		});
		return rows
	}

	reportData(){
	  switch(this.state.report) {
		  case 'channels':
			return this.props.channels
		
		case 'packages':
			return this.props.packages
			
		default:
		    return []
	  }
	}

	placeholder () {
		return (   
			<div>
		        <h1 className="display-3">Reports</h1>
		        <p className="lead" cursor="pointer" onClick={this.loadChannelData}>C3 Configuration</p>
				
		    </div>
    	);
	}
	/*	<p className="lead"><Link to="">Project Change Requests</Link></p>
				<p className="lead"><Link to="">Project - Rebrands</Link></p>
					*/

	componentWillReceiveProps() {
	}

	handleCategorySwitch = (e) => {
		const name = e.target.name;
		const value = e.target.value;
		this.setState({ [name]: value});

		console.log(`name ${name}, value ${value}`);
	}

	handleSubselection = (e) => {
		this.setState({c4RptSecondInput: e.target.value, })
		switch( e.target.value) {
			case 'input3':
			return  this.props.ReportGetAllPackages()
		}

	}

	handleReportSwitch = (e) => {
		const selectedAction = e.target.value;

		if (selectedAction == 'c3') {
			this.setState(prevState => ({
				report: 'channels',
				isLoading: true
			}), this.props.ReportGetAllChannels)
		}

		if (selectedAction == 'c4') {
			this.setState(prevState => ({
				report: 'packages'
			}))
		
		}
	}

	render () {
		const {filename, isLoading, reports, catSelection, repSelection, isReportSelected, c4RptFirstInput, c4RptSecondInput} = this.state;

		return (
		   <div className="reports">
				{this.placeholder()}

				<div className="flexMode">
					<span className="spanFlexMode">
						<InputLabel htmlFor="catSelection"></InputLabel>
						<Select value={catSelection} name={'catSelection'} onChange={(e) => this.handleCategorySwitch(e)}>
							<MenuItem value="select">Select Category</MenuItem>
							<MenuItem value={'Cat1'}>Cat 1</MenuItem>
							<MenuItem value={'Cat2'}>Cat 2 </MenuItem>
							<MenuItem value={'Cat3'}>Cat 3 </MenuItem>
						</Select>
					</span>
					<span className="spanFlexMode">
						<label>Report Name:</label>
						<Select value={repSelection} name="repSelection" onChange={(e) => this.handleReportSwitch(e)}>
							<MenuItem defaultValue={'select'}>Select Report</MenuItem>
							{reports && reports.map((report, index) => <MenuItem key={index} value={report.actOn}>{report.name}</MenuItem>)}	
						</Select>
					</span>
				</div>

				{ this.state.report === 'packages' ?  (
					<div>
					<span>
						<label>Input 1:</label>
						<Select name="c4RptFirstInput" value={c4RptFirstInput} placeholder={'Select Provider'} onChange={(e) => this.handleSubselection(e)}>
							<MenuItem value={'Def'}>Select</MenuItem>
							<MenuItem value={'Provider'}>Provider</MenuItem>
							<MenuItem value={'Region'}>Region</MenuItem>
							<MenuItem value={'Zone'}>Zone</MenuItem>
						</Select>
					
					</span>
					<span className="spanFlexMode">
						<label>Input 2:</label>
						<Select name="c4RptSecondInput" defaultValue={c4RptSecondInput} value={c4RptSecondInput} onChange={(e) => this.handleSubselection(e)}>
							<MenuItem value={'Def'}>Select</MenuItem>
							<MenuItem value={'input2'}>Input 2</MenuItem>
							<MenuItem value={'input3'}>Input 3</MenuItem>
							<MenuItem value={'input4'}>Input 4</MenuItem>
						</Select>
					
					</span>
				</div>
				) : null}
				
				
				<div>
					<CSVLink data={this.csvData()} headers={this.csvHeader()} filename={filename} target={'_blank'}>
					 <GetAppIcon />
					</CSVLink>
					
					{this.props.isLoading
					? <CircularProgress />
					: (
						<Table id="t1">
							<TableHeaders data={this.csvHeader()} />
							<TableContent data={this.csvData()} />
						</Table>
					)}
					
				</div>
			</div>
		)
	}
}


const mapDispatchToProps = dispatch => {
	return {
		ReportGetAllChannels: () => dispatch(ReportGetAllChannels()),
		ReportGetAllPackages: () => dispatch(ReportGetAllPackages()),
	}
}

const defaultState = ({
	state: {},
	channels: [],
	packages: [],
	isLoading: false
})
const mapStateToProps = (state=defaultState) => {
	return ({
		state: state,
		channels: state.RptDetailsReducer.data,
		packages: state.RptPackagesReducer.data,
		isLoading: false
	})
}

//function mapStateToProps(state, props) {
//	return {
//		state: state,
//		channels: state,
//	}
// }



// export default connect(mapStateToProps)(Reports);
export default connect(mapStateToProps, mapDispatchToProps)(Reports)


/*	<table>
						<thead>
						<tr>
							<th>Channel Name</th>
							<th>Channel Description</th>
						</tr>
						</thead>
						<tbody>
							{Object.entries(channels).map(([key, channel]) =>
								<tr>
									<td>{channel.channel_name}</td>
									<td>{channel.channel_description}</td>
								</tr>
							)}
						</tbody>
					</table>	*/

/*	<report-details
					channel_data={JSON.stringify(channelInfo.channelDetails)}
					format_type={channelInfo['formatType']}
					package_data={JSON.stringify(generalInfo.packageDetails)}
					format={JSON.stringify(RefChannelFormat)} 
					reach={JSON.stringify(RefReach)} 
					type={JSON.stringify(RefChannelType)} 
					category={JSON.stringify(RefChnlCategory)}
					edit={editChannel}
				></report-details>	*/

Open in new window

Avatar of roger v

ASKER

Hi Leakim971 - any ideas? I need to get this working asap
line 219 to 226 :
{this.props.isLoading
					? <CircularProgress />
					: (
						<Table id="t1">
							<TableHeaders data={this.csvHeader()} />
							<TableContent data={this.csvData()} />
						</Table>
					)}

Open in new window


put me to line 150 :
isLoading: true

and so 144
handleReportSwitch = (e) => {

and so 181
<Select value={repSelection} name="repSelection" onChange={(e) => this.handleReportSwitch(e)}>

you said it did it for << 2 sets of select boxes >>
look like only one line 181

back to line 144+
it look like you spin it only when the selection is "c3"
but you set state like :

			this.setState(prevState => ({
				report: 'channels',
				isLoading: true
			}), this.props.ReportGetAllChannels)

Open in new window


could you post the code of the callback  "this.props.ReportGetAllChannels" ?

do a try without the callback to see if it spin fine :
			this.setState({
				report: 'channels',
				isLoading: true
			})

Open in new window

Avatar of roger v

ASKER

Here is the code from redux part:

import CRGqlEndpoint,  {buildGQLFields} from '../reportsActions/RptGqlEndpoint';

export const REPORT_ALL_CHANNELS = 'REPORT_ALL_CHANNELS';
export const GOT_ALL_CHANNELS_REPORT = 'GOT_ALL_CHANNELS_REPORT';
export const ERROR_GETTING_ALL_CHANNELS_REPORT = 'ERROR_GETTING_ALL_CHANNELS_REPORT';

export const REPORT_ALL_PACKAGES = 'REPORT_ALL_PACKAGES'
export const GOT_ALL_PACKAGES_REPORT = 'GOT_ALL_PACKAGES_REPORT'
export const ERROR_GETTING_ALL_PACKAGES_REPORT = 'ERROR_GETTING_ALL_PACKAGES_REPORT'

export function ReportGetAllChannels () {
    return dispatch => {
        const query = `
            {
                AllChannel{
                  sk_chnl_id
                  channel_name
                  channel_description
                  call_sign
                
                }
            }`;
        dispatch({
            type: REPORT_ALL_CHANNELS,
            notice: {
                type: 'info',
                message: 'Getting all channels for report',
                show: false
            }
        })
        return CRGqlEndpoint(query)
        .then(response => {
            dispatch({
                type: GOT_ALL_CHANNELS_REPORT,
                data: response.data.AllChannel,
                notice: {
                    type: 'success',
                    message: 'Successfully retrieved all channels for report',
                    show: false
                },
                error: {}
            });
        }).catch(err => {
            dispatch({
                type: ERROR_GETTING_ALL_CHANNELS_REPORT,
                notice: {
                    type: 'error',
                    message: 'Failed to retrieve channels for report',
                    show: true
                },
                error: err
            });
        });
    }
}

export function ReportGetAllPackages () {
    return dispatch => {
        const query = `
            {
                AllPackage{
                 pkg_id
                 pkg_nm
                }
            }`;
        dispatch({
            type: REPORT_ALL_PACKAGES,
            notice: {
                type: 'info',
                message: 'Getting all packages for report',
                show: false
            }
        })
        return CRGqlEndpoint(query)
        .then(response => {
            dispatch({
                type: GOT_ALL_PACKAGES_REPORT,
                data: response.data.AllPackage,
                notice: {
                    type: 'success',
                    message: 'Successfully retrieved all packages for report',
                    show: false
                },
                error: {}
            });
        }).catch(err => {
            dispatch({
                type: ERROR_GETTING_ALL_PACKAGES_REPORT,
                notice: {
                    type: 'error',
                    message: 'Failed to retrieve packages for report',
                    show: true
                },
                error: err
            });
        });
    }
}

Open in new window

Maybe you miss that part :

do a try without the callback to see if it spin fine :
			this.setState({
				report: 'channels',
				isLoading: true
			})

Open in new window

Avatar of roger v

ASKER

you said it did it for << 2 sets of select boxes >>
look like only one line 181

-- I don't understand what you mean; I have a total of 4 select boxes; the first set of two select boxes, on selecting C3, the spinner should fire off and display until the data is loaded onto the page. Upon selecting "C4" from the select box, then the next two select boxes below them should show; once 'Input 3' is selected from second select box , that should fire off the spinner again and display until all data is loaded.
I didn't write this code - this was handed to me in this condition - this is literally my 4th day looking at any react and redux code.
I found the following one time only :
<Select value={repSelection} name="repSelection" onChange={(e) => this.handleReportSwitch(e)}>

but now I got it, you use this component 4 times

so a nice test would be to check if the spin start without the callback
Avatar of roger v

ASKER

"so a nice test would be to check if the spin start without the callback"

Here is the code with some of the changes that you suggested, that I understood and made - now the callback for 'C3' doesn't work:

import React,  { Component } from 'react';
import { connect } from 'react-redux';
import Table from '@material-ui/core/Table';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import {  Route, Link } from 'react-router-dom';
import {CSVLink} from 'react-csv';


import Header from '../components/header';
import Navbar from '../components/navbar';
import ReportDetails from '../components/rptComponents/reportDetails'
import TableHeaders from '../components/reports/tableHeaders'
import TableContent from '../components/reports/tableContent'
import { CircularProgress, FormControl, Input, InputLabel } from '@material-ui/core';
import GetAppIcon from '@material-ui/icons/GetApp';
import { ReportGetAllChannels, ReportGetAllPackages } from "../redux/actions/reportsActions/ReportsActions";
import { idlePeriod } from '@polymer/polymer/lib/utils/async';
import '../css/reports.less'
import '../css/home.less';

function toKey(s) {
	return s.split("_").map((s, i) => i > 0 ? s.slice(0,1).toUpperCase() + s.slice(1, s.length) : s).join("")
  }


function toLabel(s) {
	return s.split("_").map((s, i) => s.slice(0,1).toUpperCase() + s.slice(1, s.length)).join(" ")
  }


class Reports extends Component {
	constructor(props) {
		super(props);

		this.state = {
			report: '',
			filename: 'my-data.csv',
			isLoading: false,
			tableHeaderData: [],
			reports: [
				{ name: 'C3 Report', id: 1, actOn: 'c3'},
				{ name: 'C4 Report', id: 2, actOn: 'c4'},
				{ name: 'C5 Report', id: 3, actOn: 'c5'}
			],
			categories: {name: 'Cat 1'},
			catSelection: 'Select a Category',
			repSelection: 'Select Report Type',
			isReportSelected: false,
			c4RptFirstInput: '',
			c4RptSecondInput: ''
		}

	}

	componentDidMount () {
		const {dispatch, id} = this.props;

	}

	handleChange (e) {
		// this.setState({ input: e.target.value });
	}

	csvHeader () {

		const  data = this.reportData()
		if(data.length === 0) return []
		const keys = Object.keys(data[0])
		return keys.map((k) => {
			const label  = toLabel(k)
			const key = toKey(k)
			return { label, key }
		})
		
	}

	
	csvData () {

		const  data = this.reportData()
		if(data.length === 0) return []
		const values = Object.entries(data);
		
		const keys = Object.keys(data[0])

		const rows = values.map(entries => {
			const record = entries[1];
			return keys.reduce((acc, key, i) => {
				acc[toKey(key)] = record[key]
				return acc
			}, {})

		});
		return rows
	}

	reportData(){
	  switch(this.state.report) {
		  case 'channels':
			return this.props.channels
		
		case 'packages':
			return this.props.packages
			
		default:
		    return []
	  }
	}

	placeholder () {
		return (   
			<div>
		        <h1 className="display-3">Reports</h1>
		        <p className="lead" cursor="pointer" onClick={this.loadChannelData}>C3 Configuration</p>
				
		    </div>
    	);
	}
	/*	<p className="lead"><Link to="">Project Change Requests</Link></p>
				<p className="lead"><Link to="">Project - Rebrands</Link></p>
					*/

	componentWillReceiveProps() {
	}

	handleCategorySwitch = (e) => {
		const name = e.target.name;
		const value = e.target.value;
		this.setState({ [name]: value});

		console.log(`name ${name}, value ${value}`);
	}

	handleSubselection = (e) => {
		this.setState({c4RptSecondInput: e.target.value, })
		switch( e.target.value) {
			case 'input3':
			return  this.props.ReportGetAllPackages()
		}

	}

	handleReportSwitch = (e) => {
		const selectedAction = e.target.value;

	/*	if (selectedAction == 'c3') {
			this.setState(prevState => ({
				report: 'channels',
				isLoading: true
			}), this.props.ReportGetAllChannels)
		}	*/
		if (selectedAction == 'c3'){
			this.setState({report: 'channels',
			isLoading: 'true'
			})
		}

		if (selectedAction == 'c4') {
			this.setState(prevState => ({
				report: 'packages'
			}))
		
		}
	}

	render () {
		const {filename, isLoading, reports, catSelection, repSelection, isReportSelected, c4RptFirstInput, c4RptSecondInput} = this.state;

		return (
		   <div className="reports">
				{this.placeholder()}

				<div className="flexMode">
					<span className="spanFlexMode">
						<InputLabel htmlFor="catSelection"></InputLabel>
						<Select value={catSelection} name={'catSelection'} onChange={(e) => this.handleCategorySwitch(e)}>
							<MenuItem value="select">Select Category</MenuItem>
							<MenuItem value={'Cat1'}>Cat 1</MenuItem>
							<MenuItem value={'Cat2'}>Cat 2 </MenuItem>
							<MenuItem value={'Cat3'}>Cat 3 </MenuItem>
						</Select>
					</span>
					<span className="spanFlexMode">
						<label>Report Name:</label>
						<Select value={repSelection} name="repSelection" onChange={(e) => this.handleReportSwitch(e)}>
							<MenuItem defaultValue={'select'}>Select Report</MenuItem>
							{reports && reports.map((report, index) => <MenuItem key={index} value={report.actOn}>{report.name}</MenuItem>)}	
						</Select>
					</span>
				</div>

				{ this.state.report === 'packages' ?  (
					<div>
					<span>
						<label>Input 1:</label>
						<Select name="c4RptFirstInput" value={c4RptFirstInput} placeholder={'Select Provider'} onChange={(e) => this.handleSubselection(e)}>
							<MenuItem value={'Def'}>Select</MenuItem>
							<MenuItem value={'Provider'}>Provider</MenuItem>
							<MenuItem value={'Region'}>Region</MenuItem>
							<MenuItem value={'Zone'}>Zone</MenuItem>
						</Select>
					
					</span>
					<span className="spanFlexMode">
						<label>Input 2:</label>
						<Select name="c4RptSecondInput" defaultValue={c4RptSecondInput} value={c4RptSecondInput} onChange={(e) => this.handleSubselection(e)}>
							<MenuItem value={'Def'}>Select</MenuItem>
							<MenuItem value={'input2'}>Input 2</MenuItem>
							<MenuItem value={'input3'}>Input 3</MenuItem>
							<MenuItem value={'input4'}>Input 4</MenuItem>
						</Select>
					
					</span>
				</div>
				) : null}
				
				
				<div>
					<CSVLink data={this.csvData()} headers={this.csvHeader()} filename={filename} target={'_blank'}>
					 <GetAppIcon />
					</CSVLink>
					
					{this.props.isLoading
					? <CircularProgress />
					: (
						<Table id="t1">
							<TableHeaders data={this.csvHeader()} />
							<TableContent data={this.csvData()} />
						</Table>
					)}
					
				</div>
			</div>
		)
	}
}

//	<dfw-excel-export source="html-table" filename="fromHTML" html-table-id="t1"></dfw-excel-export>

const mapDispatchToProps = dispatch => {
	return {
		ReportGetAllChannels: () => dispatch(ReportGetAllChannels()),
		ReportGetAllPackages: () => dispatch(ReportGetAllPackages()),
	}
}

const defaultState = ({
	state: {},
	channels: [],
	packages: [],
	isLoading: false
})
const mapStateToProps = (state=defaultState) => {
	return ({
		state: state,
		channels: state.RptDetailsReducer.data,
		packages: state.RptPackagesReducer.data,
		isLoading: false
	})
}

//function mapStateToProps(state, props) {
//	return {
//		state: state,
//		channels: state,
//	}
// }



// export default connect(mapStateToProps)(Reports);
export default connect(mapStateToProps, mapDispatchToProps)(Reports)

Open in new window

now the callback for 'C3' doesn't work:

the test is to know if you get the spin, nothing else...
Avatar of roger v

ASKER

"the test is to know if you get the spin, nothing else..."

No - the spinner doesn't work either. Now when I select 'C3' nothing happens - there is no error either; nothing in the console to show that it's even going to the reducer either - just nothing happens.
could you post you package.json file ?
Avatar of roger v

ASKER

Here is the package.json - not sure how that would help but here it is:

{
  "name": "mySystem",
  "version": "1.0.2",
  "description": "",
  "private": true,
  "main": "src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --mode development --open",
    "build": "webpack --mode production"
  },
  "repository": {
    "type": "git",
    "url": "ssh://xxx.yyyyy.xxx/abc.git"
  },
  "babel": {
    "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
    ],
    "plugins": [
      "@babel/plugin-proposal-object-rest-spread",
      "@babel/plugin-syntax-dynamic-import",
      "@babel/plugin-syntax-import-meta",
      "@babel/plugin-proposal-class-properties",
      "@babel/plugin-proposal-json-strings",
      [
        "@babel/plugin-proposal-decorators",
        {
          "legacy": true
        }
      ],
      "@babel/plugin-proposal-function-sent",
      "@babel/plugin-proposal-export-namespace-from",
      "@babel/plugin-proposal-numeric-separator",
      "@babel/plugin-proposal-throw-expressions",
      "@babel/plugin-proposal-export-default-from",
      "@babel/plugin-proposal-logical-assignment-operators",
      "@babel/plugin-proposal-optional-chaining",
      [
        "@babel/plugin-proposal-pipeline-operator",
        {
          "proposal": "minimal"
        }
      ],
      "@babel/plugin-proposal-nullish-coalescing-operator",
      "@babel/plugin-proposal-do-expressions",
      "@babel/plugin-proposal-function-bind"
    ]
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/polyfill": "^7.4.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.22",
    "@fortawesome/free-regular-svg-icons": "^5.10.2",
    "@fortawesome/free-solid-svg-icons": "^5.10.2",
    "@fortawesome/react-fontawesome": "0.1.0-11",
    "@material-ui/core": "^4.3.3",
    "@material-ui/icons": "^3.0.2",
    "@webcomponents/webcomponentsjs": "^2.2.10",
    "apollo-fetch": "^0.7.0",
    "chart.js": "^2.8.0",
    "es6-promise": "^4.2.8",
    "file-saver": "^2.0.2",
    "fuse.js": "^3.4.5",
    "lodash": "^4.17.15",
    "material-ui-upload": "^1.2.1",
    "moment": "^2.24.0",
    "notistack": "^0.4.3",
    "npm": "^6.11.2",
    "pwa-helpers": "^0.9.1",
    "react": "^16.9.0",
    "react-chartjs-2": "^2.7.6",
    "react-dom": "^16.9.0",
    "react-redux": "^5.1.1",
    "react-router-dom": "^4.3.1",
    "redux": "^3.7.2",
    "redux-thunk": "^2.2.0",
    "reselect": "^4.0.0",
    "save-dev": "^2.0.0",
    "url-search-params-polyfill": "^5.1.0",
    "whatwg-fetch": "^2.0.3"
  },
  "devDependencies": {
    "@babel/cli": "^7.5.5",
    "@babel/core": "^7.5.5",
    "@babel/plugin-external-helpers": "^7.2.0",
    "@babel/plugin-proposal-class-properties": "^7.5.5",
    "@babel/plugin-proposal-decorators": "^7.4.4",
    "@babel/plugin-proposal-do-expressions": "^7.5.0",
    "@babel/plugin-proposal-export-default-from": "^7.5.2",
    "@babel/plugin-proposal-export-namespace-from": "^7.5.2",
    "@babel/plugin-proposal-function-bind": "^7.0.0",
    "@babel/plugin-proposal-function-sent": "^7.5.0",
    "@babel/plugin-proposal-json-strings": "^7.0.0",
    "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4",
    "@babel/plugin-proposal-numeric-separator": "^7.0.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
    "@babel/plugin-proposal-optional-chaining": "^7.0.0",
    "@babel/plugin-proposal-pipeline-operator": "^7.5.0",
    "@babel/plugin-proposal-throw-expressions": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/plugin-syntax-import-meta": "^7.0.0",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "@babel/register": "^7.5.5",
    "babel-loader": "^8.0.6",
    "css-loader": "^0.28.9",
    "exports-loader": "^0.7.0",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.2.0",
    "imports-loader": "^0.8.0",
    "jshint": "^2.10.2",
    "jshint-loader": "^0.8.4",
    "less": "^3.10.3",
    "less-loader": "^4.1.0",
    "redux-immutable-state-invariant": "^2.1.0",
    "style-loader": "^0.19.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.39.2",
    "webpack-babel-multi-target-plugin": "^2.3.0",
    "webpack-cli": "^3.3.7",
    "webpack-dev-server": "^3.8.0",
    "react-csv": "^1.1.1"
  }
}

Open in new window

replace :
<Select value={repSelection} name="repSelection" onChange={(e) => this.handleReportSwitch(e)}>
by :
<Select value={repSelection} name="repSelection" onChange={this.handleReportSwitch}>

also replace (line 109):
{this.props.isLoading
by :
{isLoading
Avatar of roger v

ASKER

I tried that - now the spinner just keeps spinning but the data is not loaded onto the webpage (even though I see that the redux call is made and the data is being retrieved - it's just not loading onto the page, and the spinner keeps spinning)
there's actualy no code to change the state isLoading back to false when the data is fully loaded
so no reason it stop to sping right?
Avatar of roger v

ASKER

Sorry - I'm don't understand your statement;
I just saying I don't see any code set to stop the spinning
Avatar of roger v

ASKER

Yes that's probably why it's not stopping and the data is not loading. Can you suggest how to fix that?
I think you need to use redux here, what you original code was showing :

So add this to your root reducer :
const initState = {
    isLoading: false, // <--- this line

Open in new window

and this test :
    if(action.type == "SET_LOADING_STATE") {
        return {
            ...state,
            isLoading: action.state
        }
    }

Open in new window


replace :
		const {filename, isLoading, reports, catSelection, repSelection, isReportSelected, c4RptFirstInput, c4RptSecondInput} = this.state;

Open in new window

by :
		const {filename, reports, catSelection, repSelection, isReportSelected, c4RptFirstInput, c4RptSecondInput} = this.state;
		const { isLoading } = this.props;

Open in new window


new handleSwitch function to set the isLoading boolean using redux :

  handleReportSwitch = (e) => {
    const selectedAction = e.target.value;
    if (selectedAction == 'c3') {
      this.props.setLoadingState(true);
      this.setState(prevState => ({
        report: 'channels'
      }), ReportGetAllChannels)
    }
    else if (selectedAction == 'c4') {
      this.setState(prevState => ({
        report: 'packages'
      }))
    }
  }

Open in new window


new mapDispatchToProps, defaultState and mapStateToProps :

const mapDispatchToProps = dispatch => {
  return {
    ReportGetAllChannels: () => dispatch(ReportGetAllChannels()),
    setLoadingState: state => {
      dispatch({ type: "SET_LOADING_STATE", state: state })
    }
  }
}

const defaultState = ({
  state: {},
  channels: [],
  packages: []
})

const mapStateToProps = (state = defaultState) => {
  return ({
    state: state,
    channels: state.RptDetailsReducer.data,
    packages: state.RptPackagesReducer.data,
    isLoading: state.isLoading
  })
}

Open in new window


if it still spin, you just need to stop it after ajax call done so where you have :
if(type == GOT_ALL_CHANNELS_REPORT) {
just set isLoading to false
or add a new dispatch here (the third line) :

        return CRGqlEndpoint(query)
            .then(response => {
                dispatch({ type: "SET_LOADING_STATE", state: false }); //<--- this one 
                dispatch({
                    type: GOT_ALL_CHANNELS_REPORT,

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of roger v
roger v
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
this is what I show you here in my previous comment
const { isLoading } = this.props;