Can't access to response object with props - reactjs

Im building an app with reactjs & redux and facing the following problem.
So basically I have a function like this :
onAdmissionFormSubmit(e){
e.preventDefault();
const { user } = this.props
console.log(user);
// If I do this const id = user.member.externalMemberId ....
// doesnt throw an error but if I log my const id it just says its undefined
}
It actually logs my object but if want to access the data inside of the object like user.member.externalMemberId it actually doesnt return an error but it will just says undefined.
What is it that im doing wrong?
console log of user: http://prntscr.com/fcxmou

According to your comments it seems that user is undefined, that leads me to believe that either you don't have a user object in this.props or you don't have a props object in this.
If it is the second choice, that can happen if you don't bind the handler method in to the class. In this situation, this refers to the element that triggered the handler and not to the class like you would expect.
You should do the binding in the constructor of the class:
constructor(props) {
super(props);
this.onAdmissionFormSubmit = this.onAdmissionFormSubmit.bind(this);
}

Related

React can not access variable from return

I am very new to React and I can not solve this issue for a very long time. The idea is the following, I get some user info from database and pass it into cookies. From react side I get this cookies as JSON object and I need to render menu for user depending on values in this object. Right now I pass this object that I get from cookies from parent Component and I try to access it from Settings component. The issue is that I can see access this object from test function, however when I try to access this data from return it gives me undefined error. The function that returns value from cookies is sync, I have no idea why that might happen, please help.....
Since this.state.shopSettings["new_orders"] is boolean, use ternary.
Don't copy props to the state inside constructor as the constructor is executed only once. So updates to the props won't be reflected in the component.
Like this
<button onClick={this.test}>
{props.shopSettings && (props.shopSettings["new_orders"] ? 'true button' : 'false button')}
</button>
It solves very easily with this code, now I can access any key from shopSettings inside return without any issues
class Index extends React.Component {
state = {
shopSettings: Cookies.getJSON('shopSettings')
}
render() {
const {shopSettings} = this.state
if (!shopSettings) {
return null
}
return (
<div>Hello</div>
)
}

I am attempting to use setState in React

I'm attempting to use setState function to a method in my App class..
example of the current code:
addRandomContact() {
this.setState({
actors: contacts.slice(0, 6)
})
}
I am expecting my contacts array to change from a length of 5 to 6.
The error I am receiving is the following:
TypeError: Cannot read property 'setState' of undefined
addRandomContact
"this" keyword will not be accessible inside this function and hence its undefined.
You have to use arrow function like below:
addRandomContact = () => {
this.setState({
actors: contacts.slice(0, 6)
})
Though it's not very clear from your given codebase what is the issue but one possible error you could make is that you are not binding addRandomContact inside constructor of that class component. Try to paste the following code in your constructor and check if it solves
this.addRandomContact = this.addRandomContact.bind(this);

why would this.state not be available in this scenario?

I have a component with the following functions:
constructor(MyProps: Readonly<MyProps>){
super(MyProps);
this.state = {suppliers: [], supplierId:0, supplierName:''};
this.addSupplier.bind(this);
}
addSupplier(){
const {supplierId} = this.state;
alert('supplierId = ' + supplierId);
}
<Button onClick={this.addSupplier}>Add</Button>
State is initialized as expected b/c this.state.supplierId is bound and displayed as expected in an html input in the component on load. The onChange handler within the html input also calls setState to update state.supplierId as expected. However, when the addSupplier() button gets triggered, the following error occurs:
TypeError: Cannot read property 'supplierId' of undefined
So for some reason, state is not available in this context. Any idea why this is?
Please use the arrow function to create the method
addSupplier = () => {}
or use the below syntax in the constructor
this.addSupplier = this.addSupplier.bind(this);
To expand on what Nikhil Goyal posted, the reason you're getting an error is because the context of this where the function is being invoked. Non-arrow functions implicitly bind their context when invoked rather then when they're declared. So, when you press the onClick on the Button component, it's searching for this.state.supplierId on the Button context.

Accessing to properties using dot notation in React throws me an error

I'm trying to access to a json object using dot notation but it throws me an error. Here's my code: https://codepen.io/manAbl/pen/aGymRg?editors=0110
I'm destructuring like this: const { weather } = this.state;
And when I do: console.log(weather) It shows me the hole json object, just fine but when I try to do console.log(weather.name) the console throws me an error
What am I doing wrong? I must be missing something easy but I can't see it and I'm stuck
I want to be able to access the properties and set them as a value on my state, so I can them write some functions to display an icon depending on what is the current weather of the location
this.state.weather is null initially (before the setState in componentDidMount is called), so you need to check if it's not null first before accessing the properties.
Alternatively, set weather to {} instead of null initially.
You initialize your state like this :
this.state = {
weather: null,
loading: true,
};
Then you're updating the weather var in your componentDidMount
componentDidMount is fired after the render method is called
So the 1st time the render method is called, your weather var is null and filled after componentDidMount is called
You should do
this.state = {
weather: {},
loading: true,
};
or check if your var isn't null

Can you use this.setState in a constructor object inside a react component?

I want this firebase on value event listener to be running inside this component at all times listening for changes in the database to then update the state. I was looking at examples and I only found that I can add this particular firebase event listener inside the constructor object. However, when I set the state I receive an error as such null is not an object(evaluating this.setState). Any Ideas on how I can get around this?
constructor(props) {
super(props);
this.props = props;
this.actions = commentActions;
this.state = {
comments: [],
loadingComments: true,
lastCommentUpdate: null,
review: props.review ? props.review : null,
login: null,
id: props.id
};
this.scrollIndex = 0;
database.ref("comments/").on("value", function(snapshot) {
console.log('DATA: ', typeof snapshot)
// console.log(this.state.comments )
this.setState({
comments:[...this.state.comments, snapshot]
})
})
}
I think you're problem is here:
database.ref("comments/").on("value", function(snapshot) {
console.log('DATA: ', typeof snapshot)
// console.log(this.state.comments )
this.setState({
comments:[...this.state.comments, snapshot]
})
})
this bit: function(snapshot) , is binding the "this" context to the caller, which is ".on" (guessing). So, we have to remove that. Make sure you call "this" in the context of the constructor, by changing it to an anonymous function, which doesn't have a "this" context of its own.. SO, the "this" is gotten from the surrounding object.
Change to: This allows for the "this" context to to be owned by parent object.
database.ref("comments/").on("value",(snapshot) => {
console.log('DATA: ', typeof snapshot)
console.log(this.state.comments )
this.setState({
comments:[...this.state.comments, snapshot]
})
})
IF this dooesn't work, then I assume "this" is not defined yet, within the confines of the constructor call, so you'll probably have better luck putting it in "ComponentDidMount" lifecycle method.
You can use setState inside a constructor, and if it is called after the end of the current execution stack as it would with a database call, it would trigger a re-render. So yes your approach would work if not for the other errors. I do however recommend doing data fetching in the componentDidMount method of a component as sited in the React.Component documentation.
componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

Resources