mrks
mrks

Reputation: 5631

Add value from inputs to array if not exists

I am rendering in my React application an Array and for each Array I have an input element. This elements gets as name the ID from the Array entryand a value can be entered.

I have a handleChange() functions, which gets the ID and the input value.

This data should be added to an Array, which I want to save to my State.

Later on, I have for each Array entry a Submit button, where I have to send the input value to an API endpoint.

constructor(props: Props) {
    super(props);
    this.state = {
        sendTransferObj: []
    };
    this.handleChange = this.handleChange.bind(this);
}

...

handleChange(transId: string, event: React.ChangeEvent<HTMLInputElement>) {
    console.log(transId, event.target.value); // returns => '123', '1'

    let inputObject = [{ id: transId, value: event.target.value }]
    let arrayForState = [];

    const index = inputObject.findIndex(inputObject => inputObject.id != transId)

    if (index === -1) {
        arrayForState.push(inputObject);
    } else {
        console.log("object already exists")
    }

    console.log(arrayForState)

    this.setState({
        ...this.state,
        sendTransferObj: arrayForState
    }); // error!
}

...

<Form.Control as="input" name={trans.id} onChange={this.handleChange.bind(this, trans.id)} />

My problem is currently in my handleChange(), where the input value gets saved to my arrayForObject for one input, but if I enter in a second input element a value, it gets overwritten.

Also I get various errors, when I later want to do a setState() for save this Array.

This is my whole component which I am using for reference (getting the Array that I render from my state with Redux): https://codesandbox.io/s/practical-ptolemy-69zbu?fontsize=14&theme=dark

Upvotes: 1

Views: 1548

Answers (1)

hbentlov
hbentlov

Reputation: 544

You need to append the inputObject to the sendTransferObj array in the current state instead of appending it to a new empty array (which will cause the overwriting). You can do this using the spread syntax

handleChange(transId: string, event: React.ChangeEvent<HTMLInputElement>) {
    let inputObject = [{ id: transId, value: event.target.value }]
    const index = inputObject.findIndex(inputObject => inputObject.id != transId)

    this.setState({
        ...this.state,
        sendTransferObj: index === -1 ? [
          ...this.state.sendTransferObj,
          inputObject
        ] : this.state.sendTransferObj
    });
}

This won't update the field when the inputObject is found, though. I would recommend storing the values in an object with the ID as keys instead (and formatting it into the desired format when requesting the API). This way, you don't have to iterate through the array to find the matching object.


constructor(props: Props) {
    super(props);
    this.state = {
        sendTransferObj: {}
    };
    this.handleChange = this.handleChange.bind(this);
}

...

handleChange(transId: string, event: React.ChangeEvent<HTMLInputElement>) {
      this.setState({
          ...this.state,
          sendTransferObj: {
            ...sendTransferObj,
            [transId]: event.target.value
          }
      }); 
  }

Upvotes: 2

Related Questions