0

Im new to react.

Parent component :

// handles parsed json order from child and retrieves parsed data
// child component calls this method by calling this.props.onAdded()    
handleAdded = (orderData) => {
    let items = orderData.items;
    let ids = '';
    items.forEach(function(item) {
      ids+=item.product_id.toString()+'&';
    });

    // some async call. 
    getProducts(ids).then((response) => {
      // here is the orderData variable changed based on value got from api...
      // lets say that it looks like orderData.item = 'something else'
      // changed orderData value like this is printed in child component after file is parsed :(
      this.handleFindProductResult(orderData, response.data);
    });
  }

Child component:

// parse json order from file input
getOrderFromFile = (file) => {
    let reader = new FileReader();
    reader.readAsText(file);
    reader.onload = () => {
      const parsed_order = JSON.parse(reader.result); // parsed_order.item = 'something'
      console.log('parsed:', parsed_order); // returns parsed_order.item = 'something else'
      this.props.onAdded(parsed_order);
    };
    reader.onerror = (error) => {
       this.props.onAdded(false);
    };
}

In the parent component, I call some setState() and manipulate the value got from child component - parsed_order.

The problem is, that console.log('parsed:', parsed_order); prints changed value and not actual parsed value... I cant understand it :(

I would appreciate any help.

jma-lima
  • 3
  • 3
  • What are you doing to `parsed_order` in the child? Sounds like you're mutating it unintentionally. Remember, objects are passed by reference, so your log call is going to output whatever the value of `parsed_order` is at the time of execution, which may be _after_ you've done something else to that object. Can you include your child component logic? – monners Sep 13 '17 at 00:42
  • I dont think this is exactly it... logging `parsed_order` like its in the code should print unchanged value. Maybe I just can't wrap my head around what you wrote – jma-lima Sep 13 '17 at 01:16
  • Anyway I added commented code into description – jma-lima Sep 13 '17 at 01:17
  • Can you try something real quick: in your child component, instead of `this.props.onAdded(parsed_order)`, try `this.props.onAdded(Object.assign({}, parsed_order))` That'll tell us if you're mutating the object and it's feeding back up to your log call – monners Sep 13 '17 at 01:22
  • Possible duplicate of [console.log() shows the changed value of a variable before the value actually changes](https://stackoverflow.com/questions/11284663/console-log-shows-the-changed-value-of-a-variable-before-the-value-actually-ch) – Hamms Sep 13 '17 at 01:31
  • @monners yup. this works. Does it mean that console.log is async and waits for something?. – jma-lima Sep 13 '17 at 01:38

1 Answers1

0

You're mutating parsed_order somewhere further down in your component hierarchy. As objects are passed by reference, this updated value is fed back up into where you're trying to log out the value.

If you want to retain the original value before updating it, make sure you clone parsed_order before passing it down to the child.

To do this, replace: this.props.onAdded(parsed_order)

with

this.props.onAdded(Object.assign({}, parsed_order))

Or construct some intermediate variable that you pass down:

const originalOrder = Object.assign({}, parsed_order); this.props.onAdded(originalOrder);

monners
  • 5,174
  • 2
  • 28
  • 47