Using React Redux Loading Bar : Cannot read property 'default' of undefined - javascript

EDIT
Updated and installed the lib with its updated newer package, but now getting the following error,
TypeError: Cannot read property 'default' of undefined
Function.mapStateToProps [as mapToProps]
node_modules/react-redux-loading-bar/build/loading_bar.js:300
297 |
298 | var mapStateToProps = function mapStateToProps(state, ownProps) {
299 | return {
> 300 | loading: state.loadingBar[ownProps.scope || _loading_bar_ducks.DEFAULT_SCOPE]
301 | };
302 | };
303 |
PREVIOUS:
I am using React Redux Loading Bar from TylerMcginnis here. Please note that I am not using loading bar middleware but instead a dispatch. What am I missing or doing wrong?
TypeError: state.loadingBar is undefined
Uncaught TypeError: state.loadingBar is undefined
Redux 7
React 3
ConnectFunction Redux
React 18
js index.js:20
Webpack 7
Here is the code,
import React, { Fragment } from 'react';
import { connect } from 'react-redux';
// import LoadingBar from 'react-redux-loading';
import LoadingBar from 'react-redux-loading-bar';
function Login({ users, userKeys, loading }) {
return (
<Fragment>
<LoadingBar />
<div className='container'>
{loading ? null : (
<div>
<label htmlFor='users'>Please select a User</label>
<br />
<select id='users' name='usersList'>
{userKeys.map(id => (
<option value={id}>{users[id].name}</option>
))}
</select>
</div>
)}
</div>
</Fragment>
);
}
function mapStateToProps({ users }) {
return {
loading: users === null,
users,
userKeys: Object.keys(users)
};
}
export default connect(mapStateToProps)(Login);
Reducers index:
import { combineReducers } from "redux";
import { loadingBarReducer } from 'react-redux-loading-bar';
import questions from './questions';
import users from './users';
export default combineReducers({
loadingBarReducer,
questions,
users
});
action :
export function handleInitialData() {
return dispatch => {
dispatch(showLoading());
return getInitialData().then(({users, questions}) => {
dispatch(receiveQuestions(questions));
dispatch(receiveUsers(users));
dispatch(hideLoading());
});
};
}

Fixed the issue while creating a sandbox example for you all :D...
Main Issue:
reducer should have object/field name as loadingBar for the library to be able to recognize the reducer.
This one little change fixed the issue in reducer,
export default combineReducers({ users, loadingBar: loadingBarReducer });
Here is sandbox link

Related

How to properly set multiple states in useEffect

I'm currently learning React/hooks/redux. To do so, I'm building a react app that takes in data from a climate API.
The problem I'm having is correctly setting state for a couple of items in useEffect. One state relies on the other, so I'm trying to figure out how to properly call useEffect so I don't get infinite loops and follow best-practices.
A little background before the code included below:
-The user creates a project, and selects a city. This produces a cityId that I'm storing in my "project" state.
-On the user's dashboard, they can click a project that sends the project ID in a queryString to my ClimateData component.
-ClimateData passes the project ID queryString to the "getProjectByID" redux action to get the project state, including it's cityId.
-ClimateData includes the IndicatorList component, which brings in a list of all the climate data breakouts. I want the user to click one of these list items and have ClimateData's "indicatorByCityData" state set. So I passed ClimateData's setState function to IndicatorList and have the list call with onClicks. Is there a better way I should do this?
-On ClimateData, once I have the project's cityId, and the selected item from IndicatorList, I need to call "getIndicatorByCity" and pass both the cityId and indicator to have the result saved in the "indicatorByCityData" state
I keep trying to change how my ClimateData's useEffect is written, but I'm either getting infinite loops or errors. How can I best change this to set both states and follow best practices?
The redux actions and reducers have been tested elsewhere and work fine, so for brevity, I'll exclude them here and just focus on my ClimateData and IndicatorList components:
import React, { Fragment, useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import IndicatorList from './IndicatorList';
import Spinner from '../layout/Spinner';
import { getProjectById } from '../../actions/projects';
import { getIndicatorByCity } from '../../actions/climate';
const ClimateData = ({
getProjectById,
getIndicatorByCity,
project: { project, loading },
auth,
match
}) => {
const [indicatorByCityData, setIndicatorByCityData] = useState({});
const nullProject = !project;
useEffect(() => {
if (!project) getProjectById(match.params.id);
// Once we have the cityID, set the indicatorByCityData state, with a default selected Indicator
if (!loading) setIndicatorByCityData(getIndicatorByCity(project.cityId));
}, []);
// Get the selected indicator from IndicatorList and update the indicatorByCityData state
const setIndicator = indicator => {
setIndicatorByCityData(getIndicatorByCity(project.cityId, null, indicator));
};
return (
<Fragment>
{project === null || loading || !indicatorByCityData ? (
<Spinner />
) : (
<Fragment>
<Link to='/dashboard' className='btn btn-light'>
Back To Dashboard
</Link>
<h1 className='large text-primary'>{`Climate Data for ${project.city}`}</h1>
<IndicatorList setIndicator={setIndicator} />
</Fragment>
)}
</Fragment>
);
};
ClimateData.propTypes = {
getProjectById: PropTypes.func.isRequired,
getIndicatorByCity: PropTypes.func.isRequired,
project: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
project: state.projects,
auth: state.auth
});
export default connect(mapStateToProps, { getProjectById, getIndicatorByCity })(
ClimateData
);
/******************************************************************/
import React, { useEffect, Fragment } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Spinner from '../layout/Spinner';
import { getIndicatorList } from '../../actions/climate';
const IndicatorList = ({
getIndicatorList,
auth: { user },
climateList: { indicatorList, loading },
setIndicator
}) => {
useEffect(() => {
getIndicatorList();
}, [getIndicatorList]);
return loading ? (
<Spinner />
) : (
<Fragment>
{indicatorList.length > 0 ? (
<Fragment>
<ul>
{indicatorList.map(indicator => (
<li key={indicator.name}>
<a href='#!' onClick={() => setIndicator(indicator.name)}>
{indicator.label}
</a>
<br />- {indicator.description}
</li>
))}
</ul>
</Fragment>
) : (
<h4>No climate indicators loaded</h4>
)}
</Fragment>
);
};
IndicatorList.propTypes = {
auth: PropTypes.object.isRequired,
climateList: PropTypes.object.isRequired,
setIndicator: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
climateList: state.climate
});
export default connect(mapStateToProps, { getIndicatorList })(IndicatorList);

what is the reason of not reading the property of props variables?

update: i removed this from this.props. but now nothing is showing in the localhost.
i am trying to write a blog page in react. Here is my blog.js:
import React from 'react'
const Blog=props=>{
const {title,author,content}=this.props
return(
<div>
<h2>{title}</h2>
<h5><i>{author}</i></h5>
<br/>
<h3>{content}</h3>
</div>
)
}
export default Blog
and my App.js is below:
import React,{Component} from 'react';
import Blog from './Blog'
class App extends Component {
render(){
const posts=[
{
title:'First',
author:'Anonymous',
content:'first Post',
},
{
title:'Second',
author:'Anonymous',
content:'Second Post',
},
{
title:'third',
author:'Anonymous',
content:'Second Post',
},
]
return (
<div className="container">
<Blog postData={posts}/>
</div>
);
}
}
export default App ;
while i excute npm start there is no error but in the broswer it is saying:
TypeError: Cannot read property 'props' of undefined
Blog
C:/Myfiles/python/Django/djangorest/booklearn/test-cases/src/Blog.js:5
2 |
3 |
4 | const Blog=props=>{
> 5 | const {title,author,content}=this.props
6 | return(
7 |
8 | <div>
i am running out of options. How can i solve this thing?
i have started reactjs very recent. any advice will be much appreciated.
You are using a functional component and passing in props as an argument to your function (props =>). You do not need to use this.props just props will work.
You are passing in an array of posts under the prop name 'postData'. In your blog component you need to:
import React from 'react'
const Blog=props=>{
return props.postData.map((post) => {
const { title, author, content } = post;
return (
<div key={title}>
<h2>{title}</h2>
<h5><i>{author}</i></h5>
<br/>
<h3>{content}</h3>
</div>
);
});
}
export default Blog;
Remove this since its not a class and props are being passed as the first parameter of the function.
import React from 'react'
const Blog = (props) => {
const { title,author,content } = props;
return(
<div>
<h2>{title}</h2>
<h5><i>{author}</i></h5>
<br/>
<h3>{content}</h3>
</div>
)
}
export default Blog

Trouble accessing and displaying JSON using ReactJS and the fetch-api

everyone thanks for the help!
I have looked at several similar questions but have not been able to extrapolate their answers to solve my problem.
I am using a ReactJS application to consume JSON from a website. I'm using the code from https://pusher.com/tutorials/consume-restful-api-react and changing it to fit my situation.
Currently, when I view index.js, I get the error "TypeError:
assetList.assets is undefined." Given the the JSON and code below, what do I need to change to
display a list of the assets and their properties?
I would like something like the display to look like the Desired Display below.
Desired Display.
There are two 2 assets:<br/>
id: 1317 Filename: PROCESS_FLOW.pdf
id: 1836 Filename: 004527_FS.jpg
JSON consumed from website
{"totalNumberOfAssets":2,
"assets":[
{"id":"1317","attributes":{"Filename":["PROCESS_FLOW.pdf"]}},
{"id":"1836","attributes":{"Filename":["004527_FS.jpg"]}}
]}
components/assetList.js
import React from 'react'
const AssetList = ({assetList}) => {
return (
<div>
There are {assetList.totalNumberOfAssets} assets:
{assetList.assets.map((asset) => (
<div>
id: {asset.id} filename: {asset.filename}
</div>
))}
</div>
)
};
export default AssetList
App.js
import React, {Component} from 'react';
import AssetList from './components/assetList';
class App extends Component {
render() {
return (
<AssetList assetList={this.state.assetList} />
)
}
state = {
assetList: []
};
componentDidMount() {
fetch('http://ligitaddress/api/v1/asset')
.then(res => res.json())
.then((data) => {
this.setState({ assetList: data })
})
.catch(console.log)
}
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
On your first render, the value of this.state.assetList is an array:
state = {
assetList: []
};
However you are passing it into <AssetList>
const AssetList = ({assetList}) => {
return (
<div>
There are {assetList.totalNumberOfAssets} assets:
{assetList.assets.map((asset) => (
<div>
id: {asset.id} filename: {asset.filename}
</div>
))}
</div>
)
};
The line saying assetList.assets.map is trying to call map() on something that is undefined. (you can access the property assets on an array and it will be undefined) It seems like it expects assetList to be an object with an assets array in it, but in your parent component assetList is initialized to an array... in short you're confusing yourself as to what kind of data you expect to be where.
Either change your initial state to reflect how you expect it to be passed into <AssetList>:
state = {
assetList: {
assets: []
}
};
And/or change your <AssetList> component to properly check its prop:
const AssetList = ({assetList}) => {
return (
<div>
There are {assetList.totalNumberOfAssets} assets:
{Array.isArray(assetList.assets) && assetList.assets.map((asset) => (
<div>
id: {asset.id} filename: {asset.filename}
</div>
))}
</div>
)
};
This is happening because your components/assetList.js is trying to access assetList.assets on assetList.assets.map without it being defined.
When the API request is made and has not returned yet, the assets on assetList have not being defined, since assetList on App.js is initialized to an empty array.
You can replace the line on components/assetList.js with assetList.assets && assetList.assets.map(...) and that should do it

React Components, MongoDB and passing a Key - TypeError: Cannot read property '_id' of undefined

So I'm trying to pass a field from a MongoDB into a React Component as such:
import React from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { Players } from './../imports/api/players';
import TitleBar from './../imports/UI/TitleBar';
import AddPlayer from './../imports/UI/AddPlayer';
import Player from './../imports/UI/Player';
const renderPlayers = (playersList) => {
return playersList.map((player) => {
return <Player key={player._id} />;
});
};
But the component isn't able to read the passed in player._id value.
import React from 'react';
import { Players } from './../api/players';
export default class Player extends React.Component {
render() {
return (
<p key={this.props.player._id}>
{this.props.player.name} has {this.props.player.score} point(s).
<button onClick={() => {Players.update(this.props.player._id, { $inc: { score: 1 } });}}>+1</button>
<button onClick={() => {Players.update(this.props.player._id, { $inc: { score: -1 } });}}>-1</button>
<button onClick={() => Players.remove(this.props.player._id)}>x</button>
</p>
);
}
}
Functionality wise - the code works as intended - just not as a component here because player._id isn't able to be passed in. How do I go about passing the player._id field in properly?
Error: TypeError: Cannot read property '_id' of undefined
I thought it might be because there was no data entries in the DB - but I made sure to make a few beforehand and test that, didn't work unfortunately.
In order to use _id or fields of the player object in the child component, you should pass a player object as props to child component from the Parent component. Check the modified code below
const renderPlayers = (playersList) => {
return playersList.map((player) => {
return <Player key={player._id} player={player} />;
});
}
then your child component will work fine.

Typescript mapStateToProps not updating the component props

I just started using typescript so pardon me if I am staring right at the solution. I have a component as follows
import './weatherInfo.css';
import * as React from 'react';
import { connect } from 'react-redux';
import IWeatherInfo from '../../models/WeatherInfo';
import {IApplicationState} from '../../reducers';
import WeatherInfo from './weatherInfoItem';
interface IWeatherInfoList{
weatherInfoList:IWeatherInfo[]
}
class WeatherInfoList extends React.Component<IWeatherInfoList> {
componentWillReceiveProps(){
console.log("Component will recieve props"); <------ 1
}
render() {
console.log(this.props.weatherInfoList);
return (
<div className="weatherInfoContainer">
{this.props.weatherInfoList.map((weatherInfoItem, index)=>{
debugger
return (<WeatherInfo key={index} {...weatherInfoItem}/>);
})}
</div>
);
}
}
function mapStateToProps(state: IApplicationState):IWeatherInfoList {
<------- 2
return {
weatherInfoList: state.weatherInfo.citiesWeatherData
}
}
const mapDispatchToProps = {
};
export default connect(mapStateToProps, mapDispatchToProps)(WeatherInfoList);
state.weatherInfo.citiesWeatherData is of type IWeatherInfo[]
Now whenever I update the store state all is looking good, the store get updated. But the component doesn't get new props (hence it isn't rerendered). So I put a break point at 2 and 1. It stops at 2 but not at 1. I tried changing the type of weatherInfoList to a string array and then it is working. What am I missing here?

Categories