Kevin Riordan
Kevin Riordan

Reputation: 89

unable to access reactive nested object returned by useFetch in <script setup> but i am able to access in the html

So I am trying to create a flow where there is a form, when they user modifies the form useFetch is triggered and the results on the page update. things are mostly working well i am able to access the currentPokemon variable within the html and reactivity is working great. The issue is that I am trying to access parts of currentPokemon from within the so that the chart i define will also be reactive.

The graph_data show in the below is in the currentPokemon object, but i cant access it from within <script setup>

<script setup>
import { ref } from 'vue'
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
} from 'chart.js'
import { Scatter } from 'vue-chartjs'

ChartJS.register(LinearScale, PointElement, LineElement, Tooltip, Legend)

const units = ref('METRIC')
const friction = ref(1)
const payload = ref(1)
const distance = ref(1)
const time = ref(1)
const gearRatio = ref(1)
const motionProfile = ref(0.25)
const conservatism = ref(1.5)
const stage = ref('DEFAULT')


const options = {
  responsive: true,
  maintainAspectRatio: true
}


const { data: currentPokemon } = await useFetch(`http://localhost:3000/`, {
  method: "POST",
  body: {
    unit_system: units,
    motion_profile: motionProfile,
    move_time_sec: time,
    move_distance_deg: distance,
    friction: friction,
    payload: payload,
    gear_ratio: gearRatio,
    safety_factor: conservatism,
    be_stage: stage,
    manufacturers: ["Bosch"],
    motor: "DEFAULT"
  }
})

console.log(typeof(currentPokemon))
console.log(currentPokemon)
console.log(currentPokemon.graph_data)

const test = ref(currentPokemon.value)
console.log("test")
console.log(typeof(test))
console.log(test.graph_data)

const data = ref({
  datasets: [
    {
      label: 'Accel Profile 0.25 User',
      borderColor: 'red',
      backgroundColor: 'red',
      borderWidth: 1,
      pointRadius: 0,
      pointHoverRadius: 5,
      // tension: 0,
      showLine: true,
      fill: false,
      data: [
        {x: user_graph.x[0], y: user_graph.y[0]},
        {x: user_graph.x[1], y: user_graph.y[1]},
        {x: user_graph.x[2], y: user_graph.y[2]},
        {x: user_graph.x[3], y: user_graph.y[3]}
      ]
    }
  ]
})

here is the console output

✔ Vite server hmr 6 files in 54.932ms                                                                                                                         13:56:25
object                                                                                                                                                        13:56:25
[Vue warn]: Unhandled error during execution of setup function                                                                                                13:56:25
  at <App>
RefImpl {                                                                                                                                                     13:56:25
  __v_isShallow: false,
  dep: undefined,
  __v_isRef: true,
  _rawValue: {
    motormatch: {
      '1': [Object],
      '3': [Object],
      '5': [Object],
      '7': [Object],
      '10': [Object]
    },
    stage_details: { DEFAULT: [Object] },
    motioncalcs: {
      '0.5': [Object],
      '0.33': [Object],
      '0.1': [Object],
      '0.25 User': [Object]
    },
    graph_data: {
      xlabel: 'Time (s)',
      ylabel: 'Velocity (deg/s)',
      title: 'Move Profiles',
      profiles: [Array]
    }
  },
  _value: {
    motormatch: {
      '1': [Object],
      '3': [Object],
      '5': [Object],
      '7': [Object],
      '10': [Object]
    },
    stage_details: { DEFAULT: [Object] },
    motioncalcs: {
      '0.5': [Object],
      '0.33': [Object],
      '0.1': [Object],
      '0.25 User': [Object]
    },
    graph_data: {
      xlabel: 'Time (s)',
      ylabel: 'Velocity (deg/s)',
      title: 'Move Profiles',
      profiles: [Array]
    }
  }
}
undefined                                                                                                                                                     13:56:25
test                                                                                                                                                          13:56:25
object                                                                                                                                                        13:56:25
undefined                                                       

Again the goal is to have the paramater passed to the graph be reactive based on the value of currentPokemon.graph_data. I have tried using let to declare new variables and access graph_data that way, which did allow me to get the value of graph_data but it was no longer reactive.

console.log(typeof(currentPokemon))
let res_data1 =  currentPokemon.value
let graph_data1 = res_data1.graph_data
let user_graph = graph_data1.profiles[3]
console.log(user_graph)

addition note, in html {{ currentPokemon.graph_data }} works perfectly and is reactive...

Upvotes: 0

Views: 817

Answers (2)

Marc
Marc

Reputation: 5465

Whenever you use ref or computed the way you access values template vs script differs, in script you must use the value key accessor, in template you omit it because in templates the value key accessor is injected at compilation run-time.

<script setup>
const myVar = ref([]) // Array

console.log(myVar.value.length) // Outputs 0

myVar.value.push('hello')

console.log(myVar.value.length) // Outputs 1

const count = computed(() => myvar.value.length)

myVar.value.push('world')

console.log(count.value) // Outputs 2

</script>

<template>

  <div>Total Items: {{ myVar.length }}</div>
  <div>Counter: {{ count.length }}</div>

</template>

However it is not the same case when working with nested reactive reference objects which is what you want to use if you are altering inner values of a nested object where you want to react to those nested alterations:

<script setup>
const myObject = reference({
  myData: [] // Array
})

console.log(myObject.myData.length) // Outputs 0

myObject.myData.push('hello')

console.log(myObject.myData.length) // Outputs 1

</script>

<template>
  
  <div>Total Items: {{ myObject.myData.length }}</div>

</template>

Upvotes: 1

Kevin Riordan
Kevin Riordan

Reputation: 89

Not sure if this is the best way to do this... I tried using reactive and a few other methods but this finally worked for me

/ Data pased to scatter plot
const data = computed({
   get() {
    let res_data1 =  currentPokemon.value
    let user_graph = res_data1.graph_data.profiles[3]

    let dataset = {datasets: [
    {label: 'Accel Profile 0.5',
      fill: false,
      borderColor: 'blue',
      backgroundColor: 'blue',
      borderWidth: 1,
      // pointBackgroundColor: ['#000', '#00bcd6', '#d300d6'],
      // pointBorderColor: ['#000', '#00bcd6', '#d300d6'],
      pointRadius: 0,
      pointHoverRadius: 5,
      fill: false,
      // tension: 0,
      showLine: true,
      data: [
        {x: 0, y: 0},
        {x: 0.5, y: 2},
        {x: 0.5, y: 2},
        {x: 1, y: 0}]},
    {label: 'Accel Profile 0.33',
      fill: false,
      borderColor: 'orange',
      backgroundColor: 'orange',
      borderWidth: 1,
      pointRadius: 0,
      pointHoverRadius: 5,
      // tension: 0,
      showLine: true,
      data: [
        {x: 0, y: 0},
        {x: 0.33, y: 1.49},
        {x: 0.66, y: 1.49},
        {x: 1, y: 0}]
    },
    {
      label: 'Accel Profile 0.1',
      borderColor: 'green',
      backgroundColor: 'green',
      borderWidth: 1,
      pointRadius: 0,
      pointHoverRadius: 5,
      // tension: 0,
      showLine: true,
      fill: false,
      data: [
        {x: 0, y: 0},
        {x: 0.1, y: 1.11},
        {x: 0.9, y: 1.11},
        {x: 1, y: 0}]
    },
    {
      label: 'Accel Profile 0.25 User',
      borderColor: 'red',
      backgroundColor: 'red',
      borderWidth: 1,
      pointRadius: 0,
      pointHoverRadius: 5,
      // tension: 0,
      showLine: true,
      fill: false,
      data: [
        {x: user_graph.x[0], y: user_graph.y[0]},
        {x: user_graph.x[1], y: user_graph.y[1]},
        {x: user_graph.x[2], y: user_graph.y[2]},
        {x: user_graph.x[3], y: user_graph.y[3]}
      ]
    }
  ]}

    return dataset
  },
  // setter
  set(newValue) {
    // Note: we are using destructuring assignment syntax here.
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})

Upvotes: 0

Related Questions