Jerry
Jerry

Reputation: 1583

Unusual Typescript execution sequence - Angular/Ionic

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!

Upvotes: 0

Views: 62

Answers (1)

Poul Kruijt
Poul Kruijt

Reputation: 71901

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

Upvotes: 1

Related Questions