0

I am wondering how to make new blank array with objects in the state and how to add element in it with setState.

I want the array so:

newhosts: [
      {
      activityState : "",
      platform: "",
      pushDate: "",
      name: "",
      ip: "",
      software: [{
        vulnerability: {
          link: "",
          desc: "",
          cvss: "",
          cve: ""
        },
        vulnerable: '',
        cpe: "",
        version: "",
        vendor: "",
        name: ""

      }]
      }
    ] 

Is it okay , so to declare the array in the state? How can I add later description oder items(for example description of the host and then description of all software elements on it). And how can I add for example two softwares to the same host?

 const namearray= this.state.filteredhosts.map(host=> {
        return (
           host.software.map((sub, subindex) => { 

          if(selectedOption==="name" || selectedOption==="vendor") {
            if(sub[selectedOption]=== writtenOption){


            newState.push(host.meta.name)
            newState.push(host.meta.ip)
            newState.push(sub.name) 
            newState.push(sub.vendor)
          }

         }
          else { 
            if(sub.vulnerable===true){
            newState.push(sub.vulnerability[selectedOption])}
            newState.push(host.meta.name)
            newState.push(host.meta.ip)  
          }
        })
        )
      })

Here I must replace this "newState.push" with your function, which save the data to the state.

2 Answers 2

2

I think you have this data

state = {
   newhosts : [{hostdata1}, {hostdata2}]
}

add host description

function addHostDescription = (selectHostIp) => {
    const copyState = [...this.state.newhosts];
    const hostIndex = copyState.findIndex(host => host.ip === selectHostIp);
    copyState[hostIndex] = {...copyState[hostIndex], description : 'description content'};
    this.setState({
        newhosts : copyState
    })
}

add new software

function addNewSoftware = (selectHostIp, newSoftware) => {
    const copyState = [...this.state.newhosts];
    const hostIndex = copyState.findIndex(host => host.ip === selectHostIp);
    copyState[hostIndex].software.push(newSoftware);
    this.setState({
        newhosts : copyState
    })
}

add new host

function addNewHost = (newHost) => {
    const copyState = [...this.state.newhosts];
    copyState.push(newHost);
    this.setState({
        newhosts : copyState
    })
}
Sign up to request clarification or add additional context in comments.

5 Comments

and how can I add two different softwares to the same host?
just call addNewSoftware two times with new data
ok maybe this can work but at the beginning my array is empty?
and I must save for each host every single element at the beginning for software is exactly the same , I must add each element single
If you start newhosts : [], just call addNewHost. Then, host will be added
0

Having an array as a state-value is completely valid. Consider the sandbox I made for you: https://codesandbox.io/s/deeply-nested-inputs-mf70m

Your question gave me some inspiration and writing this out actually taught me a lot about handling nested inputs and how to update them.

This code will show you how to:

  • Create a new host object and the corresponding inputs for the user to fill.
  • Update a single host object, it's first layer such as fields activityState, platform, etc.
  • Update a single software object inside a host, including the inner vulnerability object and outer-fields such as vulnerable, cpe, etc.
  • Adding a new, additional software object to a host. And then updating those software objects.

Fill out the form with any combination of hosts and software, when you're finished hit the Click to Log Hosts button to print the finalized state.

The code:

import React from "react";
class App extends React.Component {
  state = {
    newhosts: [
      {
        activityState: "",
        platform: "",
        pushDate: "",
        name: "",
        ip: "",
        software: [
          {
            vulnerability: {
              link: "",
              desc: "",
              cvss: "",
              cve: ""
            },
            vulnerable: "",
            cpe: "",
            version: "",
            vendor: "",
            name: ""
          }
        ]
      }
    ]
  };

  handleOnChange = (event, hostindex, layer, softwareIndex) => {
    const { newhosts } = this.state;
    const copiedHosts = [...newhosts];
    const updatedHosts = copiedHosts.map((host, index) => {
      //find mathcing index to update that item
      if (hostindex === index) {
        //determine what layer of data we need to update
        if (layer === 1) {
          //we need to update activityState, platform etc...
          return {
            ...host,
            [event.target.name]: event.target.value
          };
        } else if (layer === 2) {
          //now we need to find the matching software item to update
          let updatedSoftware = copiedHosts[hostindex].software.map(
            (software, sIndex) => {
              if (softwareIndex === sIndex) {
                return {
                  ...software,
                  [event.target.name]: event.target.value
                };
              } else {
                return {
                  ...software
                };
              }
            }
          );
          return {
            ...host,
            software: updatedSoftware
          };
        } else if (layer === 3) {
          //now we need to find the matching software item to update
          let updatedSoftware = copiedHosts[hostindex].software.map(
            (software, sIndex) => {
              if (softwareIndex === sIndex) {
                return {
                  ...software,
                  vulnerability: {
                    ...software.vulnerability,
                    [event.target.name]: event.target.value
                  }
                };
              } else {
                return {
                  ...software
                };
              }
            }
          );
          return {
            ...host,
            software: updatedSoftware
          };
        }
      } else {
        //return all other hosts
        return host;
      }
    });
    this.setState({
      newhosts: updatedHosts
    });
  };

  createNewHostsForm = () => {
    const { newhosts } = this.state;

    return newhosts.map((host, hostIndex) => {
      return (
        <div>
          <h4>{`Host ${hostIndex + 1}`}</h4>
          {Object.entries(host).map(([key, value], lvl1Index) => {
            if (Array.isArray(value)) {
              const secondLayerInputs = [...value];
              return (
                <div>
                  <strong>software:</strong>
                  {secondLayerInputs.map((input, softwareIndex) => {
                    return Object.entries(input).map(([lvl2Key, lvl2Value]) => {
                      if (typeof lvl2Value === "string") {
                        return (
                          <div>
                            <label>{lvl2Key}</label>{" "}
                            <input
                              value={lvl2Value}
                              name={lvl2Key}
                              onChange={e =>
                                this.handleOnChange(
                                  e,
                                  hostIndex,
                                  2,
                                  softwareIndex
                                )
                              }
                            />
                          </div>
                        );
                      } else {
                        const thirdLayerInputs = { ...lvl2Value };
                        return Object.entries(thirdLayerInputs).map(
                          ([lvl3Key, lvl3Value]) => {
                            return (
                              <div>
                                <label>{lvl3Key}</label>{" "}
                                <input
                                  name={lvl3Key}
                                  value={lvl3Value}
                                  onChange={e =>
                                    this.handleOnChange(
                                      e,
                                      hostIndex,
                                      3,
                                      softwareIndex
                                    )
                                  }
                                />
                              </div>
                            );
                          }
                        );
                      }
                    });
                  })}
                  <button onClick={() => this.addSoftwareToHost(hostIndex)}>
                    Add Software
                  </button>
                </div>
              );
            } else {
              return (
                <div>
                  <label>{key}</label>{" "}
                  <input
                    value={value}
                    onChange={e => this.handleOnChange(e, hostIndex, 1)}
                    name={key}
                  />
                </div>
              );
            }
          })}
        </div>
      );
    });
  };

  addNewHost = () => {
    const newHostObj = {
      activityState: "",
      platform: "",
      pushDate: "",
      name: "",
      ip: "",
      software: [
        {
          vulnerability: {
            link: "",
            desc: "",
            cvss: "",
            cve: ""
          },
          vulnerable: "",
          cpe: "",
          version: "",
          vendor: "",
          name: ""
        }
      ]
    };
    this.setState({
      newhosts: [...this.state.newhosts, newHostObj]
    });
  };

  addSoftwareToHost = hostIndex => {
    const { newhosts } = this.state;
    const copiedHosts = [...newhosts];
    const newSoftwareObj = {
      vulnerability: {
        link: "",
        desc: "",
        cvss: "",
        cve: ""
      },
      vulnerable: "",
      cpe: "",
      version: "",
      vendor: "",
      name: ""
    };

    const updatedHosts = copiedHosts.map((host, index) => {
      if (hostIndex === index) {
        return {
          ...host,
          software: [...host.software, newSoftwareObj]
        };
      } else {
        return {
          ...host
        };
      }
    });

    this.setState({
      newhosts: updatedHosts
    });
  };

  handleSubmit = () => {
    console.log(this.state.newhosts);
  };

  render() {
    return (
      <div>
        {this.createNewHostsForm()}
        <div style={{ margin: "25px 0px" }}>
          {" "}
          <button onClick={this.addNewHost}>Add Host</button>
        </div>
        <button onClick={this.handleSubmit}>Click to Log Hosts</button>
      </div>
    );
  }
}

1 Comment

Yes, that was my idea. Can u help me now with advice how to integrate it with my code? I have a function, with to say "for" function and for which loop I become all elements ( I updated the question)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.