3

I am developing an Angular 2 website, and I am trying to show the information contained in an object received from the back-end, which have the following structure:

{ version: 3.0.0, gauges:{ jvm.memory.total.used:{ value: 3546546 }}}

The problems come when trying to show the attribute that has dots in its name in the HTML with (being metrics the name of the object):

{{metrics.gauges.jvm.memory.total.used}}

I have also tried this way:

metrics.gauges['jvm.memory.total.used'].value 

But althogh that way works in the controller, it won't work in the HTML. The 'jvm.memory.total.used' attribute is not the only one that has dots in its name. Do you guys see any possible reason for this to be happening? Or any way of solving this?

Thank you

David G.
  • 1,255
  • 9
  • 16

3 Answers3

0

I guess you just need to use the safe-navigation (Elvis) operator so Angular doesn't throw when it tries to render the binding while the data hasn't yet arrived from the server

{{metrics?.gauges.jvm.memory.total.used}}

or

{{metrics?.gauges['jvm.memory.total.used]'}}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • This is still not working. Is the safe-navigation feature integrated in Typesript or do I have to use any extra package? The browser keeps throwing the same error: TypeError: Cannot read property 'jvm.memory.total.used' of undefined – David G. Jun 07 '16 at 10:32
  • If a property can't be `null` or `undefined` then `?` is not necessary. Can you provide a Plunker? – Günter Zöchbauer Jun 07 '16 at 10:35
  • 1
    This ended up solving the problem. I was using it in the right way though, since I initialized the metrics attribute to an empty object in the controller constructor, so the problem was when I tried to access 'gauges'. I just had to place the question mark after gauges. Thank you Günter. – David G. Jun 08 '16 at 07:28
0

If property name is not valid then you can access it only using bracket notation.

in your current question jvm.memory.total.used is not a valid property name so the only way to access is as -

gauges['jvm.memory.total.used']

you have to provide the valid property names this is the only way to solve it.

I found a good article you can go through it for reference

Reason

when you use jvm.memory.total.used in your template it actually treat it as

jvm = {
  memory: { 
   total: {
     used: 'anyvalue'
   }
  }
}

but this is not actually present so it will not display.

murli2308
  • 2,976
  • 4
  • 26
  • 47
  • Thank you for your response. When I use the bracket notation on the controller, everything works fine. The problem comes when I use it in the HTML file as: {{metrics.gauges['jvm.memory.total.used'].value}} Then the navigatior will throw the error: TypeError: Cannot read property 'jvm.memory.total.used' of undefined – David G. Jun 07 '16 at 10:28
  • Might be a bug (or missing feature) in Angulars parser. – Günter Zöchbauer Jun 07 '16 at 10:29
  • @DavidG. are you sure that you can use bracket notation in templates ? I am not aware of it – murli2308 Jun 07 '16 at 10:59
0

You can always create a getter for the property in your component class to work around this limitation.

@Component({
   selector: 'your-component',
   template: `<p>{{ jvmMemoryTotalUsed }}</p>`
})
export class YourComponent {
   private metrics = { version: 3.0.0, gauges:{ 'jvm.memory.total.used':{ value: 3546546 }}};

   get jvmMemoryTotalUsed() {
      // make null safe if value is fetched from server
      return this.metrics.gauges['jvm.memory.total.used'];
   }
}
Vrolijkx
  • 71
  • 6
  • He said he has lot of properties which has dots in there name. then he will have to create that many getters – murli2308 Jun 07 '16 at 11:00