Related
I'm not using the immutable library and I'm working on it.
I want to update the key and value values of mapTable without changing the constant of PRICE_OPTION2_STATE.
I'd appreciate it if you could tell me how.
I have posted the results of the problem and the results I want.
//my code
tableData['option2Price'] = 50000;
const mapCopy = { ...copyState };
let tableCopy = { ...mapCopy[currentTableIndex].mapTable[findTableIndex] };
tableCopy = tableData;
mapCopy.tableCopy = tableCopy;
// problem
console.log(PRICE_OPTION2_STATE);
// initstate
const PRICE_OPTION2_STATE = [
{
id: 1,
option2Name: '',
option2LeftSelect: 'sell',
mapTable: [
{
tableId: 1,
flag: true,
option2Value: '',
option2Price: '',
discountInput2: '',
discountOption2: 'won',
option2Payment: '',
option2Tax: '',
option2settlementAmount: '',
option2RightSelect: 'sell',
},
],
},
];
PRICE_OPTION2_STATE => problem console result
[
{
id: 1,
option2Name: '',
option2LeftSelect: 'sell',
mapTable: [
{
tableId: 1,
flag: true,
option2Value: '',
option2Price: '',
discountInput2: '',
discountOption2: 'won',
option2Payment: '50000',
option2Tax: '',
option2settlementAmount: '',
option2RightSelect: 'sell',
},
],
},
]
result i want
[
{
id: 1,
option2Name: '',
option2LeftSelect: 'sell',
mapTable: [
{
tableId: 1,
flag: true,
option2Value: '',
option2Price: '',
discountInput2: '',
discountOption2: 'won',
option2Payment: '',
option2Tax: '',
option2settlementAmount: '',
option2RightSelect: 'sell',
},
],
},
]
I'll assume copyState is a reference to PRICE_OPTION2_STATE or at least is some sort of (shallow) copy of it. So to copy it, you should:
not use object spread notation at the top level, since it is an array.
not leave it at a shallow copy, but copy it deeply. So you'll also need to map the inner array and copy the objects it has.
Here is some inspiration:
// Assuming copyState has the structure of PRICE_OPTION2_STATE
// Get a deep copy
const mapCopy = copyState.map(({mapTable, ...rest}) => ({
...rest,
mapTable: mapTable.map(obj => ({...obj}))
}));
// Now this assignment will not impact copyState / PRICE_OPTION2_STATE
mapCopy[currentTableIndex].mapTable[findTableIndex] = tableCopy;
This question already has answers here:
How to Import a Single Lodash Function?
(10 answers)
Closed 1 year ago.
I want to make a copy of an object.
Following that, I plan to modify values within the copy but these
modifications should not affect the original object.
Thus I want to make a clone and presently using lodash's deepClone.
But it keeps throwing the following error:
Error!Object(...) is not a function
There is no function within my object. It is just in following structure.
They are just key values where values are either strings or booleans.
const myOriginalObject {
mainKey : {
isMobile: true,
data: {
id: '',
header: '',
flag: '',
desc1: '',
desc2: '',
logo: {
src: '',
alt: '',
},
img: {
src: '',
alt: '',
},
}
}
}
Just to test it out created a random object as follows.
And even this throws same error.
const myOriginalObject = {
b: '',
c: ''
}
This is the implementation to deep copy. myOriginalObject can be either one of above objects.
import { cloneDeep } from 'lodash/cloneDeep';
const myClone = cloneDeep(myOriginalObject);
What am I doing wrong? Pls advice. Thanks.
UPDATE:
My lodash version from package.json
"lodash": "^4.17.20",
Error:
render had an error: TypeError: Object(...) is not a function
try with this
const myOriginalObject {
mainKey : {
isMobile: true,
data: {
id: '',
header: '',
flag: '',
desc1: '',
desc2: '',
logo: {
src: '',
alt: '',
},
img: {
src: '',
alt: '',
},
}
}
}
const newObj = JSON.parse(JSON.stringify(myOriginalObject));
Now make any changes to newObj it will not reflect to myOriginalObject;
My state object is:
[
{
traveller1_dob: '',
traveller1_firstName:'',
traveller1_isPreviousTraveller: false,
traveller1_surname:'',
traveller1_title: ''
},
{
traveller2_dob: '',
traveller2_firstName:'',
traveller2_isPreviousTraveller: false,
traveller2_surname:'',
traveller2_title: ''
}
]
and my payload is:
{key: "traveller1_firstName", value: "ABC", index: 0}
key is the property of the object that needs to be updated
value: is the value we want to update
index: is the index of the traveller in state array
At the moment this is the way I updated:
let obj = state[payload.index];
obj[payload.key] = payload.value;
return _.unionBy(state, [obj], payload.key);
I am aware its not the best way.
Output should be:
[
{
traveller1_dob: '',
traveller1_firstName:'ABC',
traveller1_isPreviousTraveller: false,
traveller1_surname:'',
traveller1_title: ''
},
{
traveller2_dob: '',
traveller2_firstName:'',
traveller2_isPreviousTraveller: false,
traveller2_surname:'',
traveller2_title: ''
}
]
Ideally I want to get rid of index if it's possible.How would you do this?
You're right, you can get rid of the index, and just map over your state and check hasOwnProperty on each stateItem and compare them to the payload.key. The snippet below should solve your problem:
let state = [{
traveller1_dob: '',
traveller1_firstName: '',
traveller1_isPreviousTraveller: false,
traveller1_surname: '',
traveller1_title: ''
}, {
traveller2_dob: '',
traveller2_firstName: '',
traveller2_isPreviousTraveller: false,
traveller2_surname: '',
traveller2_title: ''
}
];
function updateState(payload) {
const updatedState = _.map(state, stateItem => {
if (stateItem.hasOwnProperty(payload.key)) {
stateItem[payload.key] = payload.value;
}
return stateItem;
});
console.log(updatedState);
return updatedState;
}
const samplePayload = {
key: "traveller1_firstName",
value: "ABC",
index: 0
};
updateState(samplePayload);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
All code will be below my question and explanation.
So what I am trying to do is update my state which is in a grandparent class, this is done for reasons to do with files, I am also using Material-UI for the text boxes.
And I'm also writing Redux without Redux, Because I can just if you see some strange things.
My grandparent class state looks like this:
state = {
value: 0,
application: {
ApplicationPK: '',
Person: [
{
PersonPK: '',
FullName: '',
TitleFK: '',
Forename: '',
MiddleNames: '',
Surname: '',
DateOfBirth: '',
HomeTelephone: '',
MobileTelephone: '',
EmailAddress: '',
LoanPurposeFK: '',
MaritalStatusFK: '',
Addresses: [
{
FlatNumber: '',
BuildingName: '',
BuildingNumber: '',
Street: '',
District: '',
Town: '',
County: '',
Postcode: '',
ResidentialStatusFK: '',
DateMovedIn: '',
IsCurrentAddress: '',
AddressPK: '',
},
],
Employment: [
{
EmploymentStatusFK: '',
Employer: '',
JobTitle: '',
Telephone: '',
MonthlyPay: '',
IsPaidByBACS: '',
PayFrequencyFK: '',
DayOfMonth: '',
DayOfWeek: '',
NextPayDate: '',
FollowingPayDate: '',
DateStarted: '',
Postcode: '',
EmploymentPK: '',
Website: '',
},
],
BankAccount: [
{
Name: '',
Sortcode: '',
AccountNumber: '',
IsAccountHolder: '',
IsJointHolder: '',
IsSoleAuthoriseDebits: '',
IsPrimary: '',
IsActive: '',
BankAccountPK: '',
},
],
},
],
},
};
I know its long but thats because it errors because mui text boxes dont like null values on load.
this is how im changing the state at the moment but its adding it as a value at the top level of the state and i want it to obviously replace the value that is inside person. this function is in the same class as the state obviously
handleChangeType = event => {
this.setState({ [event.target.name]: event.target.value });
}
and Finally the Mui Text Box looks like this:
<Input
defaultValue={this.props.state.application.Person[0].Forename}
className={classes.input}
onChange={this.props.handleChangeType}
name="Forename"
inputProps={{
'aria-label': 'Description',
}}
/>
TL:DR: How do i update the correct value in the state
I know its long but thats because it errors because mui text boxes dont like null values on load.
To avoid initializing a bunch of empty strings everywhere, you could just do:
defaultValue={((this.props.state.application || {}).Person[0] || {}).Forename || ""}
As per updating the correct state variable, I would use a different handler for each category. You must also bear in mind that your state variable here is the Person array. If you want to update anything within it, you need to pass a new array to the state. Finally, you seem to want to be able to have multiple users inside your Persons array, but your event handlers aren't given any info of which user you want to update field X or Y.
For example:
handleChangeType = (userIndex, name, event) => {
let person = Object.assign({}, this.state.Persons[userIndex]); //shallow-copy
person[name] = event.target.value
this.setState({Person: person });
}
For each object or array that's nestled, you'll need to create a copy, change the copy and then replace the original with the copy.
I have a Map like this (in ImmutableJS):
{arrayOfValues: [
{one: {inside: 'first in array'}},
{one: {inside: 'second in array'}}
]}
And I want to update the value "inside" in the second entry in the "arrayOfValues" array. How can I do it? This is what I have now and it says "Uncaught Error: invalid keyPath"
theMap.update('arrayOfValues',(list)=>{
return list.setIn([1,'one','inside'],'updated value');
})
I also tried directly this and it didn't work:
theMap.setIn(['arrayOfValues',1,'one','inside'],'updated value');
After several hours of looking for the solution, I appreciate any help. Thank you.
What you are doing is correct (see this JSBin).
const orig = Immutable.fromJS({
arrayOfValues: [
{ one: { inside: 'first in array' } },
{ one: { inside: 'second in array' } },
]
});
const updated = orig.setIn(['arrayOfValues', 1, 'one', 'inside'], 'updated value');
console.log(updated.toJS());
// {
// arrayOfValues: [
// { one: { inside: 'first in array' } },
// { one: { inside: 'second in array' } },
// ]
// }
When you call orig.setIn(), it doesn't modify orig directly. That's the whole purpose of this Immutable library. It doesn't mutate the existing data but creates a new one from the existing one.
Your setIn example works as you should see in this plunkr:
http://plnkr.co/edit/1uXTWtKlykeuU6vB3xVO?p=preview
Perhaps you are assuming the value of theMap will be changed as a result of the setIn?
As these structures are immutable, you must capture the modified value in a new variable as var theMap2 = theMap.setIn(['arrayOfValues',1,'one','inside'],'updated value');
activePane is the index of Object in Array(List) that I had to modify
case CHANGE_SERVICE:
var obj = {
title: '1212121 Tab',
service: '',
tagName: '',
preDefinedApi: '',
methodType: '',
url: '',
urlParams: [{
label: '',
name: '',
value: '',
}],
headers: [{
label: '',
name: '',
value: '',
}],
};
var activePane = state.get('activePane');
var panes = state.setIn(['panes', activePane, 'service'], action.val);
return state.setIn(['panes', activePane, 'service'], action.val);