Pds Ink
Pds Ink

Reputation: 765

Error getting JSON property in Vue js

I have encountered a strange behavior with Vue. I make an ajax call store the result (some JSON) to a Vue data property named: 'modello'.

{
  "lineaGialla": {
    "selected": false,
    "descrizione": "Questa è la descrizione della linea gialla",
    "servizi": [
      {"nomeServizio": "servizio1","descrizione":"descrizione servizio1","selected": false},
      {"nomeServizio": "servizio2","descrizione":"descrizione servizio2","selected": false},
      {"nomeServizio": "servizio3","descrizione":"descrizione servizio3","selected": false}
    ]
  }
}   

In the template, when I access the data property lineaGialla using {{modello.lineaGialla}} it works, but when I try to access a nested property, such as {{modello.lineaGialla.descrizione}}, I get an error in the console:

[Vue warn]: Error in render function: "TypeError: Cannot read property 'descrizione' of undefined"

Here the ajax call.

var getData = function(){
  return new Promise(function(resolve, reject){
    $.ajax({
      type:'get',
      url:'https://api.myjson.com/bins/w9xlb',
      dataType: 'json',
      success: function(response){
        resolve(response);
      }
    });
  });
};

Here is my Vue.

var Metromappa = new Vue({
  el: '#metromappa',
  data: {
    modello:{}
  },
  methods:{

  },
  mounted: function(){
    var self = this;
    getData().then(function(response){
      self.modello = response;
    }, function(error){
      console.log(error);
    });
  } 
})

What could it be?

Upvotes: 3

Views: 1169

Answers (1)

Bert
Bert

Reputation: 82499

The problem here is data is retrieved asynchronously, meaning your data is not there when Vue first renders the template. Here is the sequence of events:

  1. The created lifecycle event is called
  2. You make a request to the server for data
  3. Vue lifecycle completes and Vue is first rendered with no data
  4. Your ajax call for data completes
  5. Vue re-renders

The problem here is step number 3. When you try to access the descrizione property in your template

{{modello.lineaGialla.descrizione}}

lineaGialla is undefined because the data is not yet retrieved from the server. So, in essence you are trying to read the descrizione of undefined and that is a javascript error.

What you should do check to make sure you have data before you try to access properties on data that may not be populated immediately.

{{modello.lineaGialla && modello.lineaGialla.descrizione}}

Alternately, if this interpolation is in some element, you can prevent the element from rendering until there is data.

<div v-if="modello.lineaGialla">
    {{modello.lineaGialla.descrizione}}
</div>

What both of these are doing is checking to make sure that lineaGialla is a non falsy value. If it is, then it renders the data.

The reason you are OK when you render {{modello.lineaGialla}} is because Vue will just render nothing. The problem is when you try to access a property of an undefined value. That will blow up every time.

Upvotes: 2

Related Questions