0
votes

I am fetching data from the server and it's nested object. When I am trying to access nested object value it prints in console but not it the template.

For Example: consider below object

    let orders = reactive({
      firstName: "Rohan",
      lastName: "Sharma",
      payment_details: {
        order_id: 1222,
        address: {
            city: "Dwarka",
            state: "Delhi",
        },
      },
    });
  • When I print orders.value.firstName it prints the value in template
  • When I print orders.value.payment_details it prints the whole object in template
  • When I print orders.value.payment_details.order_id it's giving me error ( Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'payment_details'))

My Code

  <script>
    import { reactive, ref, onMounted } from 'vue';
    import ApiService from "@/core/services/ApiService";
    import { useRoute } from "vue-router";
    
    export default {
      name: "order-detail",
      setup() {
        const orderId = ref();
        const orderDetails = reactive({});
        const route = useRoute()
        function getOrderDetails() {
          ApiService.query("orders/"+orderId.value)
          .then(({ data }) => {
            orderDetails.value = data.data;
            console.log(orderDetails.value.payment_details.order_id);//This prints in console but  while print it in template it gives error ( Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'payment_details'))
          })
          .catch(({ err }) => {
            console.log(err);
          });
        }
        onMounted(() => {
          orderId.value = route.params.id;
          getOrderDetails();
        });
        return {
          orderDetails,
        };
      },
    };
    
  </script>
1

1 Answers

0
votes

In your code you are adding a new property called 'value' to the orderDetails reactive, and assigning data.data to it.

const orderDetails = reactive({});
const route = useRoute()
function getOrderDetails() {
  ApiService.query("orders/"+orderId.value)
    .then(({ data }) => {

      // here is where the misunderstanding happens
      orderDetails.value = data.data;

})

Lets assume data.data looks like this.

{
  firstName: 'John',
  lastName: 'Doe',
  payment_details: {
    order_id: 1222,
    address: {
      city: 'Dwarka',
      state: 'Delhi',
    },
  },
}

You expect now that orderDetails looks like data.data. What you in reality have is this:


{
  firstName: 'Rohan',
  lastName: 'Sharma',
  payment_details: {
    order_id: 1222,
    address: {
      city: 'Dwarka',
      state: 'Delhi',
    },
  },
  value: {
    firstName: 'John',
    lastName: 'Doe',
    payment_details: {
      order_id: 2000,
      address: {
        city: 'Dwarka',
        state: 'Delhi',
      },
    },
  }
}

In your template you are displaying only John(object) when you call on orderDetails.value but the whole object when you call only orderDetails. Trying to call orderDetails.value.payment_details.order_id you would expect 2000, but this will fail.

I would recommend reading about ref vs reactivity. There are many good articles describing different usecases on the subject. Here are some info: https://softauthor.com/vue3-ref-vs-reactive/ https://vuejs.org/api/reactivity-core.html