Wierdest issue I've ever faced. Array getting value before the push statement

Viewed 66

I'm working on an E-commerce project and having a weird issue in the customer address section. I'm taking input from customers and running this function on button click. (Reactjs used)

I'm getting customer information from the parent component.

Code :

saveNewAddress = () => {
    var allAddress = this.props.currentCustomer.address?this.props.currentCustomer.address:[]
    console.log(allAddress) // THIS GIVES ARRAY WITH ALREADY PUSHED OBJECT WHICH I'VE DEFINED BELOW
    const addressOBJ = {
        streetAddress: this.state.streetAddress,
        city: this.state.city,
        state: this.state.state,
        pincode: this.state.pincode,
        country: this.state.country,
        full_name:this.state.firstName + " " + this.state.lastName,
        email_address:this.props.currentCustomer.email,
        contact_number:this.props.currentCustomer.mobileNumber,
    }
    allAddress.push(addressOBJ) // ACTUAL PUSH COMMAND
    const body = {
        address:allAddress,
        customer_ID:this.props.currentCustomer.customer_ID
    }
}

I'm facing 2 issues here:

  1. When i run this function, this.props.currentCustomer.address array also gets filled with a new address object. I'm only storing customer address array in a new variable and pushing new stuff into that variable, but I don't know how the object is getting pushed in that variable as well as my props array.
  2. Even before pushing the object into the allAddress array, if I console.log it, it gives a new array with pushed value. I've defined the object, then pushed it into the array but on the 2nd line when I console log the array, it gives me already pushed data. How is that even possible?

I've tried dry running the code but can't reach any solution. Kindly help.

3 Answers

Read more about JS References and making deep/shallow copy

  1. Your allAddress is actually reference to this.props.currentCustomer.address so changing allAddress also changes this.props.currentCustomer.address (as reference behavior). You need to make copy of that. E.g. .. ? JSON.parse(JSON.stringify(this.props.currentCustomer.address)) : []

  2. Logging is processed when browser has time (async). That's why it's logging after assignment was done. Try something like console.log(JSON.stringify(allAddress))

It's about the data type of javascript. please search composite data type. Array is composite data type, the variable only stored the address of the Array, if you change it, all variable changed. so you can use deepclone when you want to assign it to a variable

In terms of the console logging, I don't think it's asynchronous- so it won't necessarily 'wait' or be called in turn.

Related