Erik
Erik

Reputation: 11

My Vue object is not reactive. It works locally but not on hosted server

I get my data using axios and set my object to the new data. I also declare the object at first with empty values.

The data displays correctly in my Vue dev tools and if I log it in the console, but as soon as I display it in my HTML

<pre>{{myObj}}</pre>

It displays the old initial empty data

My code:

export default {
 data(){
  return {
   myObj: {
    foo: "",
    bar: "",
    loo: {},
    moo: [],
   }
  }
 },
 methods: {
  getData: function(){
   axios.get('/my/url')
   .then((response)=>{
     this.myObj = response.data;
     console.log("Response data: " , response.data); //**A**
     console.log("'This data:' " , this.data.purchaseorder); //**B**
   })
   .catch((error)=>{
    //ERROR
   });
  }
 }
}

A: Displays the actual correct data from my request

B: Displays the actual correct data from my request

Things I tried: I read this documentation https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

and I saw they said a root object can't be reactive, so I wrapped "myObj" in a container object.

myData: {
 myObj: {
  foo: "",
  bar: "",
  loo: {},
  moo: [],
 }
}

and I have replaced

this.myObj = response.data;

with

Vue.set(this.myData, 'myObj', response.data);

and

this.$set(this.myData, 'myObj', response.data);

Nothing works!

My main issue is that it is working perfectly on localhost! I'm guessing it has something to do with the small delay on the hosted server as opposed to local?

UPDATE

Here are the images with the real data

Vue component data (from the Vue dev tools)

Console.log data

HTML displayed data

UPDATE 2

As requested, an MCVE

<template lang="html">
<div>
  <table>
    <thead>
      <tr>
        <th>No</th>
        <th>Product</th>
        <th>Quantity</th>
        <th>Price / mt</th>
        <th>Order Total</th>
        <th>Currency</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(detail, idx) in purchaseorder.podetail">
        <td></td>
        <td>
          <input type="text" v-model="detail.product.product_name">
        </td>
        <td><input type="number" v-model="detail.po_qty"></td>
        <td><input type="number" v-model="detail.podetailcost.po_price"></td>
        <td><input type="number" v-bind:value="parseFloat(detail.po_qty * detail.podetailcost.po_price)"></td>
        <td>
          <input type="text" v-model="detail.podetailcost.currency.currency_description">
        </td>
      </tr>
    </tbody>
  </table>
</div>
</template>

<script>
export default {
  data(){
    return { //Just to initialize the Obj
      purchaseorder: {
        podetail: [
        {
          po_qty: "",
          podetailcost: [
            {
              po_price: "",
              currency: {currency_id:"", currency_description:""},
            },
          ],
        }
      },

  },
  props: ['po_id'],
  methods: {
    getData(){
      axios.get('/procurement/get/editdata/'+this.po_id)
      .then((response)=>{
        this.purchaseorder = response.data;
        console.log("Response data: " , response.data); //Displays fine
        console.log("This data: " , this.purchaseorder); //Displays fine
      })
      .catch((error)=>{
        //TODO
      });
    }
  },
  mounted(){
    this.getData();
  }
}
</script>

My desired result (This is a screenshot from my localhost, in the MCVE I removed a lot and just included the bare minimum. Don't judge the object, I did not create the DB, but I get the data in that format.

Upvotes: 1

Views: 1247

Answers (2)

user320487
user320487

Reputation:

Change the getData method to the following, without function:

methods: {
  getData () {
    axios.get('/my/url')
     .then(response => {
       this.myObj = response.data;
       console.log("Response data: " , response.data); //**A**
       console.log("'This data:' " , this.data.purchaseorder); //**B**
     })
     .catch(error => {
       //ERROR
     });
  }
}

In this case, the context of this is bound within getData: function () { ... }

Upvotes: 0

Jefry Dewangga
Jefry Dewangga

Reputation: 849

Have you call that getData method? It doesn't call automatically by Vue. You can use mounted or created lifecycle hooks to call that method. Somekind like this,

 methods: {
  getData: function(){
   axios.get('/my/url')
   .then((response)=>{
     this.myObj = response.data;
     console.log("Response data: " , response.data); //**A**
     console.log("'This data:' " , this.data.purchaseorder); //**B**
   })
   .catch((error)=>{
    //ERROR
   });
  }
 },
 mounted () {
   this.getData()
 }

Upvotes: 0

Related Questions