I would like to rename the key like:
before: Object { check: "cargo check", settings: "Cargo.toml", "create app": "cargo new APPNAME", "build and run": "cargo run / cargo-watch / cargo build --verbose" }
after: Object { MY_NEW_KEY: "cargo check", settings: "Cargo.toml", "create app": "cargo new APPNAME", "build and run": "cargo run / cargo-watch / cargo build --verbose" }
backend:
class Entry(models.Model):
tag = models.ManyToManyField(Tag, blank=True)
title = models.CharField(max_length=160, null=True, blank=True)
desc = models.TextField(null=True, blank=True)
data = models.JSONField(null=True, blank=True)
frontend:
class Entry extends React.Component {
constructor(props){
super(props)
this.state = {
entry: this.props.entry,
edit: false,
id: this.props.entry.id,
title: "",
desc: "",
data: "", // server returns: Object { check: "cargo check", settings: "Cargo.toml", "create app": "cargo new APPNAME", "build and run": "cargo run / cargo-watch / cargo build --verbose" }
}
}
componentDidMount() {
var data=this.props.entry.data
console.log(data)
this.setState({ data: data }) //Object { check: "cargo check", settings: "Cargo.toml", "create app": "cargo new APPNAME", "build and run": "cargo run / cargo-watch / cargo build --verbose" }
}
render(){
var entry = this.state.entry;
var entryData = this.state.data; <---- data is passed to showEntryForm(....)
var edit = this.state.edit;
var toggleEdit = this.toggleEdit;
var submitFunction = this.handleSubmit;
var handleChangeFunction = this.handleChange;
var handleJsonChange = this.handleJsonChange;
return(
edit ? showEntryForm(entry, entryData, submitFunction, handleChangeFunction, handleJsonChange) <-----
: showEntry(entry, entryData, toggleEdit)
)
}
}
const showEntryForm = (entry, entryData, submitFunction, handleChangeFunction, handleDataChangeFunction) => {
return <div key={ entry.id } className="container bg-danger p-5" >
<div className="row" >
<h1>Eintrag bearbeiten</h1>
</div>
<div className="row">
<form onSubmit={ submitFunction }>
<div className="row ">
<label htmlFor="title" className="form-label">Titel</label>
<input onChange={event => handleChangeFunction(event) } type="text" name="title" defaultValue={ entry.title } className="form-control" autoFocus/>
<label htmlFor="desc" className="form-label">Description</label>
<textarea onChange={event => handleChangeFunction(event) } type="text" name="desc" defaultValue={ entry.desc } className="form-control" />
<div className="row mt-2">
{entryData ? <div> {Object.keys(entryData).map(function(keyName, keyIndex){ <------- returns the state.data
return <div key={keyIndex} className="row bg-info p-1 mt-2">
<div className="col-6">
<input name={ keyName } onChange={ event => handleDataChangeFunction(event, "key", keyName) } type="text" defaultValue={ keyName } className="form-control"/> <--------
</div>
<div className="col-6">
<input name={ keyName } onChange={ event => handleDataChangeFunction(event, "value", keyName) } type="text" defaultValue={ entryData[keyName] } className="form-control"/>
</div>
</div>
})} <button>add</button> </div>: ""}
<div>
<button type="submit">ändern</button>
</div>
</div>
</div>
</form>
</div>
</div>
}
That's the function in component Entry, to change the state.data
handleDataChangeFunction(event, keyOrValue, keyName) {
console.log("HANDLE JSON CHANGE")
var name = event.target.name;
var value = event.target.value;
var data = {...this.state.data};
if(keyOrValue === "value"){ <----- changing the value is no problem
data[keyName] = value;
this.setState({ data: data })
}
if(keyOrValue === "key") { <------ big problem
delete(data[keyName])
data = (delete(data[keyName]), data)
this.setState({ data: data})
}
}
I have tried with Object.keys(data).map and some other things, but nothing worked yet.
I guess it's either some easy thing or I should change the whole thing, including backend.
CodePudding user response:
if(keyOrValue === "key") { <------ big problem
delete(data[keyName])
data = (delete(data[keyName]), data)
this.setState({ data: data})
}
I don't really understand what you are trying to accomplish here. Deleting a key should be as easy as
delete data[keyName]
this.setState({ data })
I would suggest trying
var data = JSON.parse(JSON.stringify(this.state.data));
// your code
if(keyOrValue === "key") { <------ big problem
delete data[keyName]
data[keyName] = value
this.setState({ data })
}
CodePudding user response:
const { propsToRename, ...otherProps} = data
const newData = { newName: propsToRename, ...otherProps}
the first line is destructuring {}
rest operator ...
destructuring allows you to take out whatever key in that object and the rest operator allow you to cluster all the remaining keys and values into a new object: otherProps
do note that the rest operator must be the last one(hence the name rest)
if the rest operator is not the last one, it will end with an error (speaking in common sense, this is because any key after the rest operator is meaningless)
=============================
the 2nd line however, despite the syntax look similar, {}
is not destructuring but instead structuring (not a usual way to call this, people usually just call it an creating an "object literal", newbie like to shorten it to just the word "object")
and ...
is no longer a rest operator but a spread operator, it no longer cluster the keys and values. Instead, it spread an object's keys and values into another object
so the syntax in the 2nd line did the opposite thing of the 1st line