Property values empty in this.props - reactjs

I have the following Component that I want to render (
https://github.com/sbycrosz/react-native-credit-card-input/blob/master/src/CreditCardInput.js). Its working fine however I want to assign default card field values e.g. number, using the values props defined.
<CreditCardInput
gooble={{number: 4111111111111111}}
values={{number: 4111111111111111}}
requiresName
requiresCVC
requiresPostalCode
validatePostalCode={validatePostalCode}
cardImageFront={cardFront}
cardImageBack={cardBack}
labelStyle={addCardStyle.label}
inputStyle={addCardStyle.input}
validColor={"black"}
invalidColor={"red"}
placeholderColor={"darkgray"}
onFocus={this._onFocus}
onChange={this._onChange.bind(this)}/>
The actual CreditCardInput.js file should deconstruct these values and pre-populated the fields according to the source code in the link above:
const {
cardImageFront, cardImageBack, inputContainerStyle,
values: { number, expiry, cvc, name, type }, focused,
allowScroll, requiresName, requiresCVC, requiresPostalCode,
cardScale, cardFontFamily, cardBrandIcons,
} = this.props;
<CreditCard
...
number={number}
...
However when i debug on CreditCardInput.js during render I can see that the this.props contains values property, however this is an empty object (instead of containing the number value defined). This seems very odd behaviour. I have tested with other props passed through (E.g: gooble={{number: 4111111111111111}}) and it is populated correctly in this.props even though its exactly the same, except for the names.
So in CreditCardInput.js when I change the source code from above to using the prop gooble it works:
const {
cardImageFront, cardImageBack, inputContainerStyle,
gooble: { number, expiry, cvc, name, type }, focused,
allowScroll, requiresName, requiresCVC, requiresPostalCode,
cardScale, cardFontFamily, cardBrandIcons,
} = this.props;
<CreditCard
...
number={number}
...
However why isnt it working with this.props.values/ why is this.props.values an empty object.

Related

Bind popup returning undefined

I am following the Covid-19 Map tutorial by Coding with Adam. When each country is clicked, the popup displays the country's name along with the infection count. The COVID data can be obtained here.
My replicated example cannot properly display the infection count, returning undefined instead of a number.
const CovidMap = ({ countries }) => {
const mapStyle = {
fillColor:"white",
weight: 1,
color:"black",
fillOpacity: 1,
};
const onEachCountry = (country, layer) =>
{
layer.options.fillColor = country.properties.color;
const name = country.properties.ADMIN;
const confirmedText = country.properties.confirmedText;
layer.bindPopup(`${name} ${confirmedText}`); //confirmedText returns undefined
};
return (
<MapContainer style={{height: "90vh"}} zoom={2} center={[20, 60]}>
<GeoJSON
style={mapStyle}
data={countries}
onEachFeature={onEachCountry} />
</MapContainer>
);
};
I am certain that confirmedText's value can be accessed, because console.log() prints the value. ADMIN and ISO_A3 can be displayed by the popup, but not confirmed nor confirmedText.
UPDATE: Forgot to include the GeoJSON used to build the countries. Here it is.
FURTHER UPDATE: If I add any lines to the code that throw an error, remove the lines, and re-render the page, the popup can return the values. However, subsequent re-renderings would introduce the same problem.
From your SS it doesn't appear that confirmedText is a property of your object. Normally objects show in the terminal like { prop: 'a',... } with the ... standing in for much larger object. I'm also curious why you have to access your sub properties using the properties key word. In a normal object it would just be country.confirmedText. I (me) would start by understanding why you need to access things this way and that might explain why it's undefined.
I'd leave this as a comment but I can't do that yet.

How to use react-select-table's rows as options to react-select's input field

I have an input field that should accept multiple inputs from options that are already set. - This input field needs to appear like tag input fields so I used the React-select library:
The set options are going to come from a react-bootstrap-table so I disabled the built-in dropdown in the react-select input field.
The problem is that I cannot remove the selected items by deselecting the row from the react-bootstrap-table.
I think I am doing something wrong on how I'm passing the values between the input field and the table but can't figure it out.
Here is the codesandbox
The problem is you try to compare two Objects, however there is no generic means to determine that an object is equal to another.
You could JSON.stringify them both and compare but thats not reliable way.
Instead, you can filter the array by object key, lets say label.
In this case, your function should look like this:
const setSelected = (row: any, isSelect: any, rowIndex: any, e: any) => {
if (isSelect) {
setSelectProducts([...selectedProducts, row]);
} else {
const newArray = selectedProducts.filter(
(item) => item.label !== row.label
);
setSelectProducts(newArray);
}
};
Here is codesandbox to preview
#Edit
If you wanna do something onClear
onChange={(selectedOption, triggeredAction) => {
if (triggeredAction.action === 'clear') {
// Clear happened
}

React dynamic add select input field

I am trying Create a select field dynamically. When clicking the add button, it will dynamically add select fields. I have and issue where the values don't change.
My code can be viewed on codesandbox:
https://codesandbox.io/s/react-select-field-dynamically-uo4dy?file=/src/App.js
Take a look at my changes:
Forked sandbox
// I added a 3rd argument for the name:
const handleRoomChange = (option, index, name) => {
const value = option.value; // you had this as 'const { value } = option.value' which dereferences value twice
console.log(value);
const list = [...roomInputs];
list[index][name] = value; //you had this as list[index][value]
setRoomInputs(list);
};
// onChange passes the name as 3rd argument to handleRoomChange
<Select
name="boardBasic"
placeHolder="Board"
value={options.value}
onChange={option => handleRoomChange(option, i, "boardBasic")}
options={options}
styles={{
menu: (provided) => ({ ...provided, zIndex: 9999 })
}}
/>
You have three problems that I can see.
First, you only have a handleRoomChange function that is trying to handle both room changes and board changes. You should probably have a handleBoardChange function, as well.
Second, if you output option to the console inside handleRoomChange, you will notice that option.value is a number. So, when you proceed to set list[index][value] to value, what you're saying is that you want (for example) roomInputs[1][1] to be 1. roomInputs[1] has no 1 property, which is why you will end up with the wrong properties inside your object on submission. You need to be setting roomInputs[1].roomType to value, instead (and the boardBasic property in your handleBoardChange method, when you write it).
Third, you are trying to use object destructuring to assign object.value to your value variable...but you're trying to destructure object.value instead of destructuring object. For this reason, value is undefined every time you run the function. Replace the assignment with const { value } = option; and you will start getting defined values back.

Object properties being assigned to a form show up as object Object instead of the actual value

I'm passing an object called "team" to this function in React. The "team" object has 4 different properties.
id, playerName, typeId, and locationName.
I am populating state values like this:
const [idValue, setIdValue] = React.useState(false);
const [typeIdValue, setTypeIdValue] = React.useState(false);
const [nameValue, setNameValue] = React.useState(false);
const [locationValue, setLocationValue] = React.useState(false);
And my function looks like this that sets the state values above.
const showEdit = (team) => {
console.log(team);
setShowRosterForm(true);
setIdValue(team.id);
setTypeIdValue(team.typeId);
setNameValue(team.playerName);
setLocationValue(team.locationName);
}
I then display these values in a form like this:
const RosterForm = ({
idValue, typeIdValue, nameValue, locationValue
}) => ( ... display form fields )
But when I populate the form with these values, I just see [object Object].
But I don't understand that, because when I wite out the 'team' object to the console, I can see all the individual properties like id, typeId, playerName, and locationName.
So I'm not sure why it's an Object.
Is there a better way of going about doing this?
Thanks!
You do not need to pass in the state getters into your RosterForm(). Can you not directly use the getters typeIdValue and others to set the form?
Please print a console.log(typeIdValue) inside your RosterForm() so that you can see the value it receives.
I believe the setting of the values to the form might be incorrect. Could you update your code for setting the value to a field of your form?

Re-rendering state in Reactjs not working as expected

I have a parent component in React that holds the state of the application (I'm building a filterable table). In the state I have a the filters gathered by some inputs, the state looks like this filters: [{"filter1": "value1"}, {"filter2": "value2"}, { }, { }, ...]. The filters inputs are build in a child component FilterBar that receives the filters array as a propertie <FilterBar filters={this.state.filters}/>.
So when the user writes something in the input field it updates the state of the filters (parent) according to the field name and the new input value. So far everything works as I expected. But now I want to implement a button to clean the filters, so when the user click on it the state of the filters become empty (" " string for each filter value). I success on it, when I click the button it setState as I expected, and the table is updated as I wanted. But I'm doing some mistake, the input fields receive the new filters array properties but it doesn't clean the input text (so if I had a word or letter in the input text, it still there after the rerender, and I want the input empty as the state).
Here is the parent function to clean the filters (and I realize that it works as expected):
cleanFilters() {
let filters = this.state.filters.slice();
let f;
for (f in filters) {
filters[f]['value']="";
}
this.setState({filters: filters}, function(){this.updateData();});
}
And here is the function that renders the text inputs on the FilterBar component:
renderFilterInputs() {
var filters = [];
for (let i=0; i < this.props.totalFilters; i++) {
filters.push(<td key={i}><input type='text' className="form-control" defaultValue={this.props.filtersApplied[i].value} onChange={(evt) => this.handleFilterChange(evt, i)} /></td>);
}
return filters;
}
render() {
return (
<tr key="0" className="filters-bar">
{this.renderFilterInputs()}
</tr>
);
}
I don't understand why the text input still save the text when I click the button because it rerenders again and the filter state is empty so the defaultValue of that inputs should be ("") empty. Thanks you
Because you are using defaultValue not value means uncontrolled component. Default value will assign the initial value (default value) to input element only, it will not update the value.
Solution:
Since you are using onChange function with input element and updating the parent state also, so use controlled input field, use value property instead of defaultValue.
value = {this.props.filtersApplied[i].value}

Resources