Search code examples
javascriptreactjsecmascript-6setstate

Setting state of an object property inside array of objects based on a computation after match : reactjs


https://codesandbox.io/s/polished-bird-662mh?from-embed

I am having this an array of objects and an object with the following structure

this.state = {
               arr : [ {
                        id: "val1",
                        initialVal: "test1",
                        finalVal: "final1"
                       },
                       {
                         id: "val2",
                         initialVal: "test2",
                         finalVal: "final2"
                       },
                       {
                         id: "val3",
                         initialVal: "test3",
                         finalVal: "final3"
                       },
                       {
                         id: "val4",
                         initialVal: "test4",
                         finalVal: "final4"
                       }
                     ],
                values: [ "test1","test3"]
              }

this.obj = { field: "test1" , val:6}

I am writing a function that takes this obj as its parameter and based on the "field" value it should set the state of "finalVal" with the "val" property of obj with the following computation(if val is greater than 5 add "ok" to the field else add "cancel") and the objects whose property don't match in the "values" array of the state its "finalVal" should be set to just blank

So the output should look after setting state :

 [ 
             {
              id: "val1",
              initialVal: "test1",
              finalVal: "ok"
             },
             {
              id: "val2",
              initialVal: "test2"
              finalVal: "final2"
             },
             {
              id: "val3",
              initialVal: "test3"
              finalVal: ""
             },
             {
              id: "val4",
              initialVal: "test4"
              finalVal: "final4"
             }
 ]


//What I have tried so far

 setObjState = obj => {
    let arr = [...this.state.arr];
    let finalArr = arr.map(function(item) {
      if (item.initialVal === obj.field) {
        return { ...item, finalVal: obj.val > 5 ? "Ok" : "Cancel" };
      } else {
         if(this.state.values.includes(item.id){
              return { ...item, finalVal: "" };
          }
      }
    });
    console.log(finalArr);
    this.setState({ arr: finalArr });
  }

Solution

  • You were missing an else condition:

    setObjState = obj => {
      let arr = [...this.state.arr];
      let finalArr = arr.map(item => {
        if (item.initialVal === obj.field) {
          return { ...item,
            finalVal: obj.val > 5 ? "Ok" : "Cancel"
          };
        } else {
          if (this.state.values.includes(item.id)) {
            return { ...item,
              finalVal: ""
            };
          } else {
            return { ...item
            };
          }
        }
      });
      console.log(finalArr);
      this.setState({
        arr: finalArr
      });
    };
    

    Here's a Working CodeSandbox Sample for your ref.