0

I am trying to publish an updated object but not trying to change the state through the following code in react:

addPlaceToSearch = (place) => {
    if (place != this.state.search_text) {
      var search = $.extend({}, this.state.search);
      if (!search.added_places.includes(place)) {
        search.added_places.push(place);
        PubSub.publish('searchUpdated', search);
      }
    }
  }

Thus, I am using $.extend({}, this.state.search) to clone the object into another variable, modify that particular variable and then publish it. But when I execute the line 5, and I put a breakpoint on line 6, I can see that the this.state.search is also changed with place being pushed in it's added_places key (which I do not want). How is this happening? And how can I prevent it? I have also tried Object.assign({}, this.state.search) instead of $.extend({}, this.state.search).

EDIT

I even tried the most trivial solution, here it is:

addPlaceToSearch = (place) => {
    if (place != this.state.search_text) {
      if (!this.state.search.added_places.includes(place)) {
        var xyz = {};
        for (var key in this.state.search) {
          xyz[key] = this.state.search[key];
        }
        xyz.added_places.push(place);
        PubSub.publish('searchUpdated', xyz);
      }
    }
  }

Still, the xyz.added_places.push(place) line changes my this.state.search object too! Kindly help me out.

psr
  • 2,619
  • 4
  • 32
  • 57
  • xyz[key] is still referencing this.state.search[key], if you use xyz[key] = Object.assign({}, this.state.search[key]) it should not keep the reference? Im not 100% sure if that is whats causing it though – thsorens Oct 29 '16 at 12:24
  • `this.state.search[key]` are string/arrays/integer values, so `Object.assign({}, this.state.search[key])` is returning an empty object. – psr Oct 29 '16 at 12:35
  • Oh, now i see what you are doing. Where do "place" come from ? is that stored in this.state? because that will still be bounded to state then. So you need to assign it using Object.assign – thsorens Oct 29 '16 at 12:40

2 Answers2

0

Finally, after two hours of hard work, I figured out the solution by making a deep copy of the original array. I will read about the differences between shallow and deep copy as given in this answer, till then here is the solution:

var xyz = $.extend(true, {}, this.state.search);
xyz.added_places.push(place);
Community
  • 1
  • 1
psr
  • 2,619
  • 4
  • 32
  • 57
0

You can do this better without jQuery using Object.assign()

var xyz = Object.assign({}, this.state.search)
xyz.added_places.push(place)
Pranesh Ravi
  • 18,642
  • 9
  • 46
  • 70
  • As already mentioned in my question, I had already tried this. But I think this method also does a shallow copy of the object, whereas I would require a recursive copy since my object includes an array. – psr Oct 29 '16 at 13:07
  • 1
    This should help you https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone – Pranesh Ravi Oct 29 '16 at 13:09