Element does not exist in React's componentDidMount - javascript

I have following react component:
var ForumActivityTimeLine = React.createClass({
componentDidMount: function () {
this.showActivityLineChart()
},
showActivityLineChart() {
const lineChartSpec = getForumActivityLineChart(this.props.data.frequency)
const opt = {
renderer: "canvas",
actions: false
};
vegaEmbed('#ForumActivityLineChart', lineChartSpec, opt)
},
render() {
return (
<span>
<h5 style={{ textAlign: "center", fontWeight: "bold", display: "block", paddingTop: '2em' }}> Forum Activity Timeline</h5>
<div className="d-flex justify-content-around" style={{ paddingTop: "0.5em" }}>
<div id='#ForumActivityLineChart'></div>
</div>
</span>
)
}
})
vegaEmbed line is trying to render a line chart in the div with id ForumActivityLineChart, but it gives me following error:
embed.ts:296 Uncaught (in promise) Error: #ForumActivityLineChart does not exist
at Kn (embed.ts:296:11)
at Jn (embed.ts:259:16)
Here is the error desscription in console:
In chrome dev tools console, you can see that the corresponding div element does exist (ignore setTimeout call in snapshot, I thought if I can dirty set some timeout to let the component render first):
Here is another screenshot, where debugger stops before throwing exception:
PS: I am working on legacy react app, thats why I have var and componentDidMount.

You should not include # in the id-attribute.
Replace
<div id='#ForumActivityLineChart'></div>
with
<div id='ForumActivityLineChart'></div>

Related

React Native Country PickerView error when selecting a country

I have a country picker view component from the 'react-native-country-picker-modal' package. When I click on it it opens a list of all the countries with their flag and code, but when i click on any one of the countries i get this error "Type Error: undefined is not an object (evaluating 'countries[countryCode].name')" and "Type Error: undefined is not an object (evaluating str.indexOf)"
here is my code:
import CountryPicker from 'react-native-country-picker-modal'
const [callingCode, setCallingCode] = useState('+1')
const [countryCode, setCountryCode] = useState('US')
<CountryPicker
style={{ height: 40, width: 60 }}
countryCode={countryCode}
translation={'ita'}
withCallingCodeButton
withAlphaFilter
withFilter
visible={false}
onClose={() => {
// this.setState({showCountry : false})
}}
onSelect={(country) => {
setCallingCode(country.cca2)
setCountryCode(country.callingCode)
}}
/>
What am i doing wrong?

Cannot create property label on string error on immutable objects probably

I am getting an error which I am not able to understand or shake. What I am trying to do is that on click of a button I am trying to change the value in the text field in the form I created Howerver I am getting this error:
Cannot create property label on string for one of the instances.
Here is the function where I am trying to change the values:
getReport(ReportList) {
this.state.SPCCODE.label = 'NA';
this.state.destinationcode.label = 'NA'
}
I am declaring SPCCODE in the state as
SPCCODE: '',
destinationcode: '',
I am declaring SPCCODE as conditional render in render like so:
let DDL;
const DDLValue = servicecode.label;
if (DDLValue == 'Direct') {
DDL = <> </>;
} else if (DDLValue == 'STYD') {
DDL = <> </>;
} else {
DDL = (
<Col lg="6" style={{ marginTop: '0rem' }}>
<Label for="spcc">SPC</Label>
<Select
className="select"
id="spc"
// value={servicecode}
placeholder="Search spcCode..."
value={hide ? null : SPCCODE}
onChange={this.handleChangeSPC}
options={this.state.spcCode}
isDisabled={this.state.disable}
styles={{
control: (provided, state) => ({
...provided,
boxShadow: 'none',
// borderBottom: "1px dotted pink",
borderBottom: this.state.isEmpty4 ? '1px solid red' : '1px solid black',
}),
}}
/>
</Col>
);
}
I am handling the SPC CODE change in this function:
handleChangeSPC = SPCCODE => {
this.setState({ hide: false });
this.setState({ SPCCODE });
var spc_label = SPCCODE.label;
this.setState({ spc_label });
};
I am calling the g getReport() function from a child component table like this
passVariable() {
this.props.getReport(this.state.ReportList);
}
I am calling this onClick
On researching I am getting that may it is showing the error because the variable is immutable but have not anywhere declared it in const. Please help do not know why exactly this error is showing?
The problem is that you declare SPCCODE as string in the state then trying to access to non-existent property label inside it. It is not possible and throw type error.
To solve it, you must declare it like literal object such as:
SPCCODE: {label:''}

Test Conditionally Rendered component in React Js

I'm new to testing and I'm writing test cases for a react app.
I've a table with atoms in it.
<Table.Cell style={{ cursor: "pointer" }}>
<Icons
data-test="nameDeleteTable"
name="trash"
onClick={() =>
ConfirmBox({
title: "Confirm Deleting?",
message:
"Are you sure you want to delete this entry permanently?",
onClick: () => props.handleDelete(cell.name),
})
}
/>
</Table.Cell>
ConfirmBox has the following code
function ConfirmBox(props) {
return (
<div data-test="confirmboxAtom">
{confirmAlert({
title: `${props.title}`,
message: `${props.message}`,
buttons: [
{
label: "YES",
onClick: props.onClick,
},
{
label: "NO",
},
],
})}
</div>
);
}
confirmAlert is from a library named react-confirm-alert
The current attempt to test the table button click, gets to the onClick of <Icons ... /> using the code
const wrapper = getWrapper(component, "nameDeleteTable");
console.log("Wrapper " , wrapper);
wrapper.props().onClick();
expect(wrapper.length).toBe(1);
While checking the coverage for this, I'm able to get the onClick function to be covered but not the onClick of the ConfirmBox and I have no clue how to make it work.
You have to invoke a onClick() on whatever this react-confirm-alert renders to (I mean the html element).

How to render an Image by URL from Axios.get()

I have problems and need help with rendering an image in React. The problem is that this image is stored locally, and the URL to this image is retrieved from database with Axios.get() along with some other data. All data is showing up fine, but cannot render that image.
class Lesson extends Component {
state = {
lesson: null
};
componentDidMount() {
Axios.get("https://localhost:44372/api/Lesson/lesson/" +
this.props.location.pathname.substring(
this.props.location.pathname.lastIndexOf("/") + 1)
).then(response => {
console.log("API Response", response);
const newLesson = response.data;
this.setState({
lesson: newLesson,
});
});
}
render() {
return (<div>
<h2 style={{ textAlign: "center" }}>{this.state.lesson.title}</h2>
<p>{this.state.lesson.text}</p>
<p>{this.state.lesson.field1}</p>
<img src={this.state.lesson.img} //<-----here
alt="none"
style={{
verticalAlign: "middle",
display: "block",
margin: "auto",
marginLeft: "auto",
marginRight: "auto"
}}
/>
<div>);
In this way that image does not show up.
Error that I encounter is: Not allowed to load local resource: file:///D:/Project/FrontEnd/platform/src/images/python_img.PNG
The only way that I can get that img is to insert like this manually, but this is not what I want:
<img src={require("D:\\Project\\FrontEnd\\platform\\src\\images\\python_img.PNG")}
I thought that the problem is in componentDidMount(), as I was getting an undefined value at start, but later I just provided the same path from parent page (just to check) and the problem is the same.
I am doing something wrong...
Is a way to provide as image source a variable?
If the images itself is bundled in your react app, then its not going to work like you expect.
require() only accepts static
Things you can do
1.Render conditionally
const images = {
image1: require('./image1.jpg'),
image2: require('./image2.jpg'),
};
Then in your app
<img src={this.state.lesson.img === 'something_unique' ? images.image1 : images.image2} //<-----here
alt="none"
style={{
verticalAlign: "middle",
display: "block",
margin: "auto",
marginLeft: "auto",
marginRight: "auto"
}}
/>
2.Or if your using a bundler, you can get the public URL and append it.
<img src={process.env.PUBLIC_URL + this.state.lesson.img} />

React, Uncaught RangeError: Maximum call stack size exceeded

I'm working in react and basically I want to make an button with tooltip, right now I'm making tooltip. I'm changing css display property in order to make it visible or not during mouse enter and leave. But there is an error and I don't know what to do...
Here is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import Style from 'style-it';
var Ink = require('react-ink');
import FontIcon from '../FontIcon/FontIcon';
var IconButton = React.createClass({
getInitialState() {
return {
iconStyle: "",
style: "",
cursorPos: {},
};
},
extend(obj, src) {
Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
return obj;
},
Tooltip(props) {
var style = {};
if (this.tooltipDisplay) {
style.display = "block";
} else if (!this.tooltipDisplay) {
style.display = "none";
};
return <div className="tooltip" style={style}>{_props.tooltip}</div>;
},
showTooltip(){
this.tooltipDisplay = true;
},
removeTooltip(){
this.tooltipDisplay = false;
},
render() {
var _props = this.props,
tooltip = this.Tooltip,
opts,
tooltipDisplay = false,
disabled = false,
rippleOpacity,
outterStyleMy = {
border: "none",
outline: "none",
padding: "8px 10px",
"background-color": "red",
"border-radius": 100 + "%",
cursor: "pointer",
},
iconStyleMy = {
"font-size": 12 + "px",
"text-decoration": "none",
"text-align": "center",
display: 'flex',
'justify-content': 'center',
'align-items': 'center',
},
rippleStyle = {
color: "rgba(0,0,0,0.5)",
};
if (_props.disabled || _props.disableTouchRipple) {
rippleStyle.opacity = 0;
};
this.setState({
iconStyle: _props.iconStyle
});
this.setState({
style: _props.style
});
if (_props.disabled) {
disabled = true;
};
if (this.state.labelStyle) {
iconStyleMy = this.state.iconStyle;
};
if (this.state.style) {
outterStyleMy = this.state.style;
};
if (_props.href) {
opts.href = _props.href;
};
var buttonStyle = this.extend(outterStyleMy, iconStyleMy);
return(
<Style>
{`
.IconButton{
position: relative;
}
.IconButton:disabled{
color: ${_props.disabledColor};
}
.btnhref{
text-decoration: none;
}
`}
<a {...opts} className="btnhref" >
<tooltip text={this.props.tooltip} position={this.options} />
<button ref="button" className={"IconButton" + _props.className} disabled={disabled} style={buttonStyle}
onMouseEnter={this.showTooltip} onMouseLeave={this.removeTooltip} >
<Ink background={true} style={rippleStyle} opacity={rippleOpacity} />
<FontIcon className={_props.iconClassName}/>
</button>
</a>
</Style>
);
}
});
ReactDOM.render(
<IconButton href="" className="" iconStyle="" style="" iconClassName="face" disabled="" disableTouchRipple="" tooltip="aaaaa" />,
document.getElementById('app')
);
In console I'm getting this error:
Uncaught RangeError: Maximum call stack size exceeded
at defineRefPropWarningGetter (App.js:1053)
at Object.ReactElement.createElement (App.js:1220)
at Object.createElement (App.js:3329)
at Constructor.render (App.js:43403)
at App.js:15952
at measureLifeCyclePerf (App.js:15233)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (App.js:15951)
at ReactCompositeComponentWrapper._renderValidatedComponent (App.js:15978)
at ReactCompositeComponentWrapper._updateRenderedComponent (App.js:15902)
at ReactCompositeComponentWrapper._performComponentUpdate (App.js:15880)
I can't find out what's wrong. I know it might be something about calling a function which in turn calls another function. But I can't see anything like this in my code and I'm not sure if it's all about it. Thanks for help :)
The problem is you are calling setState from inside your render function. State changes should only happen as a result of something changing: user clicked on a button, the browser window was resized, a picture was taken, etc.
Never ever ever ever update the state while rendering (repeat that last sentence 20 times and never forget it).
Here is the problem code:
render () {
...
this.setState({
iconStyle: _props.iconStyle
});
this.setState({
style: _props.style
});
...
}
The above code would cause an infinite loop of sorts because setState causes render to be called. Since iconStyle and style are props, and props cannot change, you should use those props to build your initial state.
getInitialState() {
return {
iconStyle: this.props.iconStyle,
style: this.props.style,
cursorPos: {},
};
}
Later, if someone clicks a button and you want the iconStyle to change, you would create a click handler which updates your state:
handleClick () {
this.setState({
iconStyle: 'clicked'
});
}
This would cause your component to be rerendered and the new state would be reflected.
Think of your "state" as someone cooking and we are going to take photographs of them cooking. The initial state is "eggs cracked: no, flour poured: no, veggies chopped: no", and you take a picture of this state. Then the chef does something - cracks the eggs. The state has now changed, and you take a picture of it. Then she cuts the veggies. Again, the state has changed and you take a picture.
Each photograph in the analogy represents your "render" function - a snapshot of the "state" at a particular point in time. If every time you took a photograph the flour got poured, well we would have to take another picture because the flour was just poured. Taking another picture would cause more flour to get poured so we'd have to take another picture. Eventually you'd fill the kitchen to the ceiling with a celiac's nightmare and suffocate everybody in the room. You'd also run out of film or hard disk space on your camera.
Thanks to #RyanWheale I noticed my mistake.
In my render function I was returning a button element which called a function which changed a certain state. The returned button looked like this:
<button onclick={this.edit()} className="button-primary">Edit</button>
And my edit function changes some state and looks like this:
edit: function () {
this.setState({editing: true});
}
So, I my mistake is that I, accidentally, typed the parenthesis after this.edit. So, when the button element was being rendered, the edit function was actually called and chaos happened. Now, when I wrote
<button onclick={this.edit} className="button-primary">Edit</button>
instead of
<button onclick={this.edit()} className="button-primary">Edit</button>
it worked flawlessly.
I hope I help someone save hours of his precious life.
Cheers :)
I faced the same problem, I had installed "reactime" extension and that extension caused me this problem. Removing that extension from my chrome, solved the issue.
I got 'Maximum call stack size exceeded', and similar errors because of framer-motion API dependency, version bigger than 4.1.17 (today's version is 5.5.5). I don't figured out why yet.
For the same extensions also, got some weird errors like 'window.webkitStorageInfo' is deprecated, and similar bugs.
I had the same error in my SPFX project while running Gulp Serve. I deleted the newly added reference in my config.json file and it worked.
More details: https://fixingsharepoint.blogspot.com/2022/04/rangeerror-maximum-call-stack-size.html

Categories