0

I'm facing a very weird situation. The 2nd/3rd line of code executed before the 1st line of code, where I don't think the codes are async.

Here is how my constructor look like:

this.menu = this.navParams.get('menu')
console.log(this.menu) //code line 31

And here is the console.log result: enter image description here

To make sure the menu value still the same after page is loaded, i console.log at the ionViewDidLoad() - line 38, and the result is the same. You can see there is no "approvedBy" at this moment.

So now I execute a function, which is approveMenu()

approveMenu() {
    console.log(this.menu) //line 52

    let newMenu = this.menu //line 54
    console.log(newMenu) //line 55
    newMenu['approvedBy'] = this.currentUser.uid //line 56
    console.log(newMenu) //line 57
  }

However, after I executed the function, the "approvedBy" will be added to the menu before I put it in there. You can refer to the screenshot below, the sequence of console.log is correct, but the line 52 and line 54 console.log shouldn't have "approvedBy" right? It should only appear at line 57 because the "approvedBy" added into menu at the line 56.

enter image description here

But apparently it doesn't work as expected, please enlighten me.

Edited

Thanks to PierreDuc solving my question.

Afterwards, with the same function, it called my provider to update my DB. Here is the expansion of approveMenu()

approveMenu() {
    console.log(JSON.parse(JSON.stringify(this.menu)))

    let newMenu = this.menu
    console.log(JSON.parse(JSON.stringify(newMenu)))
    newMenu['approvedBy'] = this.currentUser.uid
    console.log(Object.assign({}, newMenu))
    console.log(Object.assign({}, this.menu))
      this.restaurantProvider.approvePendingMenu(this.menu).then(()=>{
        this.alertProvider.successful('Successful','The menu has been added to your restaurant and it can be view by public now','Noted')
        this.navCtrl.pop()
      }).catch(err=>{
        this.alertProvider.successful('Something Went Wrong',err,'Noted')
      })
  }

when I call the restaurantProvider's approvePendingMenu(this.menu) function, some code didn't process according to my expectation. Let me show you the approvePendingMenu(this.menu) first:

approvePendingMenu(menu){
    console.log(Object.assign({}, menu))
    return this.pendingSuggestiontRef.child(menu.suggestId).remove().then(()=>{
      console.log(Object.assign({}, menu)) //line 63
        delete menu.suggestId
        console.log(Object.assign({}, menu)) //line 65
        const newMenu = menu
        console.log(Object.assign({}, menu)) //line 67
        delete newMenu.restId
        console.log(Object.assign({}, menu)) //line 69
        console.log(Object.assign({}, newMenu)) //line 70
        this.restaurantListRef.child(`${menu.restId}/menuList`).push(newMenu)       
      }) 
  }

At the line 98, i delete the restId from newMenu, but it apparently delete the restId from menu as well, and I expecting it won't delete the restId from menu because it supposedly is 2 different variable right? I have try to use var, let or const, but the result still the same.

Hereby attach the console.log screenshot for your reference: enter image description here

Please advise again. Thank you!

Jerry
  • 1,455
  • 1
  • 18
  • 39
  • 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) – Ilmari Karonen Apr 16 '18 at 06:12

1 Answers1

1

It's because chrome developers tool doesn't evaluate the object until you open it (click the arrow) in the console. When you do console.log(obj), it will just log the reference. Try logging this, and it will work:

console.log(Object.assign({}, this.menu);

or

console.log(JSON.parse(JSON.stringify(this.menu));

or whatever you like. The code is performed sync, just the evaluation of the object inside the chrome console is not.

You can also try to, instead of the entire object, to just log console.log(this.menu.approvedBy). You will see it will log like you expect

Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
  • Thank you so much! It did solve my problem. But here i come will second question regarding handling of object, i have edited my question, can u please help also. – Jerry Apr 16 '18 at 07:26
  • 1
    When you do `const newMenu = menu;` you do not create a new object. You just copy the reference (a reference to some object in memory) to the object which is held into the menu variable to the `newMenu` constant. Because you have a shallow object, you can use the same `Object.assign` trick: `const newMenu = Object.assign({}, this.menu)`. This will create a new object, and the newMenu and menu variables will have different references – Poul Kruijt Apr 16 '18 at 07:37