Redirecting from one page to another while passing variables?

I have a page, let's call it /invoices.

On that page, I have a data table that contains a list of invoices related to a specific customer (the table loads all invoices using a customer number stored in a global context variable). The first column contains the invoice number. When I click on the invoice number, I want another page on the dashboard to load (let's call it /invoice-actions), while passing the invoice number so that I can use it further on that page/flow.

I already know how to create the <a> tag in the cell containing the invoice number, to make the cell clickable and creating the link to the other page. But how do I pass on the value of the cell (= the invoice number) when redirecting the user to the other page?

My answer was going to be to add ?query=value to the end of the URL, and then access it via this.$route.query in your target page, however... the router is removing the query on the arrival destination for some reason, and I'm not entirely sure why.

A working solution is actually to use Vue's <router-link> instead, not sure why the raw <a> doesn't work:

<template>
    <router-link :to="{path: '/path/to/page', query: {hello: 'world'}}">Test Link with Router Link (with path)</router-link>
    <router-link :to="{name: 'Page:<Page Name>', query: {hello: 'world'}}">Test Link with Router Link (by name)</router-link>
</template>

I tested this by then adding a ui-template on the destination page with:

<template>
    <div>
        Query Param "hello" = {{ queryParam }}
    </div>
</template>

<script>
    export default {
        data() {
            // define variables available component-wide
            // (in <template> and component functions)
            return {
                queryParam: null
            }
        },
        mounted() {
            // code here when the component is first loaded
            this.queryParam = this.$route.query?.hello
        }
    }
</script>

Thank you, that worked!

But instead of sending the string 'world', how do I send either a msg or item?

Tried referencing them using double brackets, but that didn't work. The URL just contains the brackets and the variable name.

EDIT: Dropped the single quotes, and it works. Thank you.

You mentioned you'd want to send the invoice number, so:

<router-link :to="{name: 'Page:<Page Name>', query: {invoiceNumber: item.invoiceNumber}}">Test Link with Router Link (by name)</router-link>

Assuming the item was the row of data within the <template> of the v-data-table

No need for any double brackets here, as we've told Vue that the to is a dynamic variable with : in it, so it treats the contents as JavaScript.

1 Like

What if I want to store invoiceNumber in msg.invoiceNumber as well as display it in the div?

Not sure I understand the context of msg here? You've navigated from Page 1 > Page 2. No Node-RED messages are passed between them in order to make this happen?

Where are you receiving or sending msg?

If you mean on the arrival page, ithe whole component can access the query parameter with this.$route.query.invoiceNumber as mentioned above.

You can do whatever you like with it then, rendering in a div:

<div>{{ $route.query.invoiceNumber }}</div>

or sending it on with a button click:

<v-btn @click="send({payload: $route.query.invoiceNumber})">Send Invoice Number</v-btn>

Let's say for example, after the user is redirected to the other page, I want to do an API call using a http request node, with the invoice number in the URL https://example.com/api/invoices/{{invoiceNumber}}.

To get some more information about the invoice before displying it in the template node.

How do I reference the invoice number? And how can I take a look at it in a debug node for example?

I'd be making an API call (using something like fetch) from within the ui-template node.

If you have your API hosted in Node-RED using the http-in/http-out nodes, then your API call within the Vue client could handle everything, e.g.

[
    {
        "id": "3ae1fe5fec1d4b4f",
        "type": "http in",
        "z": "9c18a4bf6ab4e5c1",
        "name": "",
        "url": "/invoices/:invoiceNumber",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 820,
        "y": 240,
        "wires": [
            [
                "f9438d85d70dd835"
            ]
        ]
    },
    {
        "id": "05d3b69b57dac523",
        "type": "http response",
        "z": "9c18a4bf6ab4e5c1",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1250,
        "y": 240,
        "wires": []
    },
    {
        "id": "f9438d85d70dd835",
        "type": "change",
        "z": "9c18a4bf6ab4e5c1",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "req.params.invoiceNumber",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1080,
        "y": 240,
        "wires": [
            [
                "05d3b69b57dac523",
                "84d7120f9493ce46"
            ]
        ]
    },
    {
        "id": "d6066823247f012e",
        "type": "ui-template",
        "z": "9c18a4bf6ab4e5c1",
        "group": "41970c5cd2a6cef0",
        "page": "",
        "ui": "",
        "name": "",
        "order": 0,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n    <v-btn @click=\"loadInvoice(123)\">Make API Call</v-btn>\n    <pre>{{ invoice }}</pre>\n</template>\n\n<script>\n    export default {\n        data() {\n            // define variables available component-wide\n            // (in <template> and component functions)\n            return {\n                invoice: null\n            }\n        },\n        mounted() {\n            // code here when the component is first loaded\n            this.queryParam = this.$route.query?.hello\n        },\n        methods: {\n            loadInvoice: async function (invoiceNumber) {\n                const response = await fetch('/node-red/invoices/' + invoiceNumber)\n                this.invoice = await response.json()\n            }\n        }\n    }\n</script>",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 900,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "84d7120f9493ce46",
        "type": "debug",
        "z": "9c18a4bf6ab4e5c1",
        "name": "debug 378",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1270,
        "y": 280,
        "wires": []
    },
    {
        "id": "41970c5cd2a6cef0",
        "type": "ui-group",
        "name": "API Call Example",
        "page": "bbc7b44a426b2b01",
        "width": "6",
        "height": "1",
        "order": -1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "bbc7b44a426b2b01",
        "type": "ui-page",
        "name": "Debugging Problems",
        "ui": "c2e1aa56f50f03bd",
        "path": "/problems",
        "icon": "bug",
        "layout": "notebook",
        "theme": "129e99574def90a3",
        "order": 12,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "c2e1aa56f50f03bd",
        "type": "ui-base",
        "name": "Dashboard",
        "path": "/dashboard",
        "showPathInSidebar": false,
        "navigationStyle": "default"
    },
    {
        "id": "129e99574def90a3",
        "type": "ui-theme",
        "name": "Another Theme",
        "colors": {
            "surface": "#000000",
            "primary": "#0094ce",
            "bgPage": "#f0f0f0",
            "groupBg": "#ffffff",
            "groupOutline": "#d9d9d9"
        },
        "sizes": {
            "pagePadding": "6px",
            "groupGap": "6px",
            "groupBorderRadius": "9px",
            "widgetGap": "12px"
        }
    }
]

Hmm I see, so there is no way to store the number in msg.something?

If that's a necessity, then you could emit a msg from the ui-template using the send() function? Docs

But given what you've explained you're trying to build, not entirely sure it's necessary?

Is there any way to send the data without needing user interaction? Like part of the mounted() code?

yes - just call the send() function inside the mounted () { ... }

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.