2

I have JSON called by fetch request that looks like this:

[{
    "nameSecond": "",
    "Id": "",
    "First": {
      "nameFirst": "",
      "Id": ""
    }
  },
  {
    "nameSecond": "",
    "Id": "",
    "First": {
      "nameFirst": "",
      "Id": ""
    }
  },
  {
    "nameSecond": "",
    "Id": "",
    "First": {
      "nameFirst": "",
      "Id": ""
    }
  },
  {
    "nameSecond": "",
    "Id": "",
    "First": {
      "nameFirst": "",
      "Id": ""
    }
  }
]

I want to replace an object of another JSON to every object of this JSON. The second JSON which is going to be added to first JSON looks like this:

[{
        "nameFirst": "",
        "id": ""
},
{
        "nameFirst": "",
        "id": ""
},
{
        "nameFirst": "",
        "id": ""
},
{
        "nameFirst": "",
        "id": ""
 }]

What I did is that when ChangeObjectFirst was run ,the object is clicked will be replace by the object Firstof firstJSON and new data will be shown.

 <div onClick={((e) => this.ChangeObjectFirst(e, i))}>Change</div>

I used Object.assign({}, itemToReplace) to replace objects but The main problem is that it will be done just for the first time. For the second time or more clicked object will not be replaced by object First and there will be this TypeError: el is undefined

class App extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        data: [],
        dataNew: [],
        library: null,
        libraryNew: null,
    }
}
componentDidMount() {
    fetch('/json.bc', {
        method: 'POST',
    })
        .then(response => response.text())
        .then(text => {
            const Maindata = JSON.parse(text.replace(/\'/g, '"'))
            this.setState(state => ({
                ...state,
                data: Maindata
            }), () => {
                this.reorganiseLibrary()
            })
        }).catch(error => console.error(error))

    fetch('/json2.bc', {
        method: 'POST',
    })
        .then(response => response.text())
        .then(text => {
            const Maindata = JSON.parse(text.replace(/\'/g, '"'))
            this.setState(state => ({
                ...state,
                dataNew: Maindata
            }), () => {
                this.reorganiseLibraryNew()
            })
        }).catch(error => console.error(error))
}

reorganiseLibrary = () => {
    const { data } = this.state;
    let library = data;
    library = _.chunk(library);
    this.setState({ library })

}

reorganiseLibraryNew = () => {
    const { dataNew } = this.state;
    let libraryNew = dataNew
    libraryNew = _.chunk(libraryNew);
    this.setState({libraryNew})
}

renderLibrary = () => {
    const { library } = this.state;
    if (!library || (library && library.length === 0)) {
        return ''
    }
    return library.map((item, i) => (
        <div>
            {item.First.nameFirst}
            {item.nameSecond}
        </div>
    ))
}

renderLibraryNew = () => {
    const { libraryNew } = this.state;
    if (!libraryNew || (libraryNew && libraryNew.length === 0)) {
        return ''
    }
    return libraryNew.map((item, i) => (
        <div>
            {item.nameFirst}
            <div onClick={((e) => this.ChangeObjectFirst(e, i))}>Change</div>
        </div>
    ))
}

render() {
    const { library, libraryNew } = this.state;
    return (
        <div>
            {this.renderLibrary()}
            {this.renderLibraryNew()}
        </div>
    )
}

ChangeObjectFirst = (e, i) => {
    const itemToReplace = this.state.libraryNew[i];
    let { data } = this.state;
     data = data.map(el => {
        el['First'] = Object.assign({}, itemToReplace);
    });
    this.setState({ data: data });
}
}
ReactDOM.render(<App />, document.getElementById('Result'))

1 Answer 1

1

The issue is that while updating, you haven't returned the new data from map. Also since you are using library variables for rendering, you need to call reorganiseLibrary after updating data. A better implementation without mutation would be as below

ChangeObjectFirst = (e, i) => {
    const itemToReplace = this.state.libraryNew[i];
    let { data } = this.state;
     data = data.map((el, idx) => {
         return Object.assign({}, el, { First: itemToReplace});
    });
    this.setState({ data: data }, ()=> {this.reorganiseLibrary()});
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks @Shubham Khatri but nothing has happened. even there is not any error.
A simpler way would be using object spread: { ...el, First: itemToReplace }
And for the first time it is not be replaced too.
@Rajesh you mean something like this:data = data.map((el, idx) => { return Object.assign({}, { ...el, First: itemToReplace }); });
@sahar object spread is a replacement for Object.assign. Its a suggestion not a solution
|

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.