Home > Mobile >  How to pass a Vue3 Ref variable by reference? (and what the missing "global" variable is)
How to pass a Vue3 Ref variable by reference? (and what the missing "global" variable is)

Time:09-19

I wrote the following Vue3 component (TemperatureOutside.vue)

<template>
  <div class='text-large-1 text-weight-bold'>
    {{ temperature }}°
  </div>
</template>

<script setup lang='ts'>
import { ref } from 'vue';
import { setupMqtt } from './mqtt';

const temperature = ref(-100)
setupMqtt('temperature', temperature)
</script>

setupMqtt is defined in mqtt.ts:

import { connect } from 'mqtt'
import { Ref } from 'vue'

export const setupMqtt = (topic: string, data: Ref): void => {
    const client = connect('mqtt://192.168.10.2:1884')
    const topics = [`dash/${topic}`]
    // removed some setup lines that do not matter
    client.on('message', function (topic: string, message: Buffer) {
      // the key line is below
      data.value = JSON.parse(message.toString())
    })
}

I wanted to pass data and react to the change of its .valuein the calling component.

My problem: the program runs fine when I comment out setupMqtt('temperature', temperature). If it is present, I get on the console the following breaking error:

vue-router.mjs:35 [Vue Router warn]: uncaught error during route navigation:
warn @ vue-router.mjs:35
triggerError @ vue-router.mjs:3439
(anonymous) @ vue-router.mjs:3163
Promise.catch (async)
pushWithRedirect @ vue-router.mjs:3157
push @ vue-router.mjs:3089
install @ vue-router.mjs:3520
use @ runtime-core.esm-bundler.js:4349
start @ client-entry.js?t=1663525498443:63
Promise.then (async)
(anonymous) @ client-entry.js?t=1663525498443:82

vue-router.mjs:3441 ReferenceError: global is not defined
    at node_modules/readable-stream/lib/_stream_readable.js (_stream_readable.js:48:21)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/readable-stream/readable-browser.js (readable-browser.js:1:28)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/mqtt/lib/store.js (store.js:8:18)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/mqtt/lib/client.js (client.js:7:15)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/mqtt/lib/connect/index.js (index.js:3:20)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
triggerError @ vue-router.mjs:3441
(anonymous) @ vue-router.mjs:3163
Promise.catch (async)
pushWithRedirect @ vue-router.mjs:3157
push @ vue-router.mjs:3089
install @ vue-router.mjs:3520
use @ runtime-core.esm-bundler.js:4349
start @ client-entry.js?t=1663525498443:63
Promise.then (async)
(anonymous) @ client-entry.js?t=1663525498443:82

vue-router.mjs:35 [Vue Router warn]: Unexpected error when starting the router: ReferenceError: global is not defined
    at node_modules/readable-stream/lib/_stream_readable.js (_stream_readable.js:48:21)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/readable-stream/readable-browser.js (readable-browser.js:1:28)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/mqtt/lib/store.js (store.js:8:18)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/mqtt/lib/client.js (client.js:7:15)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)
    at node_modules/mqtt/lib/connect/index.js (index.js:3:20)
    at __require (chunk-OL3AADLO.js?v=fff356dc:9:50)

I fail to understand what the referenced global variable is and I fear that my attempt to pass by reference fails miserably somewhere.

CodePudding user response:

First, you can't modify the ref or any value like that, by this way you just update the data param inside the function but not the ref value in the component.

Maybe you can return the ref value from the setupMqtt function, like this.

TemperatureOutside.vue

<template>
  <div class='text-large-1 text-weight-bold'>
    {{ temperature }}°
  </div>
</template>

<script setup lang='ts'>
import { ref } from 'vue';
import { setupMqtt } from './mqtt';

const temperature = ref(await setupMqtt('temperature', -100))

</script>

mqtt.ts:

import { connect } from 'mqtt'
import { Ref } from 'vue'

export const setupMqtt = async (topic: string, data: Ref): Promise<Ref> => {
    const client = connect('mqtt://192.168.10.2:1884')
    const topics = [`dash/${topic}`]
    // removed some setup lines that do not matter
    return new Promise((resolve, reject) => {
         client.on('message', function (topic: string, message: Buffer) {
         // the key line is below
         resolve(JSON.parse(message.toString()))
    })
    })
}

CodePudding user response:

ref() takes the argument and returns it wrapped within a ref object with a .value property. The .value property of a ref is reactive.

Could you try changing the setupMqtt() function in TemperatureOutside.vue file:

const temperature = ref(-100);
setupMqtt('temperature', temperature.value);
  • Related