# Create a template table from message object

**URL:** <https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173>\
**Category:** General\
**Created:** [26 October 2019 16:46 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173 "2019-10-26T16:46:06Z")\
**Posts on this page:** 8\
**Page:** 2

<div class="post-metadata">

**Author:** ![cuxcrider](https://avatars.discourse-cdn.com/v4/letter/c/58f4c7/32.png) [@cuxcrider](https://discourse.nodered.org/u/cuxcrider)\
**Post date:** [29 October 2019 15:40 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/21 "2019-10-29T15:40:52Z")

</div>

@TotallyInformation, @bakman2

I have a table working now both with a Vue based UIbuilder version and a jquery UIbuilder version (I figured I better get both working to figure out what I prefer). I'll post the code to get your feedback or maybe help others. It's nothing special, but at least it's another example.

**Before I do so, I have a couple questions so maybe I can make a couple tweaks:**

Taking @bakman2 suggestion, I flattened my object to an array of objects.

```auto
{
	"devices": [
		{
			"serial": "1a",
			"channel": 0,
			"status": "running",
			"value": 100,
			"setpoint": 200
		},
		{
			"serial": "1a",
			"channel": 1,
			"status": "running",
			"value": 100,
			"setpoint": 200
		}
	]
}

```

This made creating a table much easier, but is there really no downside to this format versus my original object:

```auto
{ "serialNum": {
            "1a": {
                    "channel": {
                        "0": {
                            "status": "running",
                            "value" : 100.0,
                            "setpoint": 200.0
                        },
                        "1": {
                            "status": "running",
                            "value" : 100.1,
                            "setpoint": 200.1
                        }
                    }
                },
            "2a": {
                    "channel": {
                        "0": {
                            "status": "running",
                            "value" : 200.0,
                            "setpoint": 300.0
                        },
                        "1": {
                            "status": "running",
                            "value" : 200.1,
                            "setpoint": 300.1
                        }
                    }
                },
            "3a": {
                    "channel": {
                        "0": {
                            "status": "stopped",
                            "value" : 300.0,
                            "setpoint": 400.0
                        },
                        "1": {
                            "status": "stopped",
                            "value" : 300.1,
                            "setpoint": 400.1
                        }
                    }
                }
            }
    }

```

Maybe I do not understand objects like I thought I did. I would have guessed my original object would be desirable because I could quickly drill down to a value of a specific channel on a specific board. For example the program would just quickly skip over all the objects that do not match the desired serial number. In the new object the program has to potentially loop through every single object in the array to find what I am looking for. For making a table, especially a sortable table, I suppose it does not matter because every row is basically an object. Maybe it just depends on the final use case how to structure the object.

**My other questions relate to Vue:**

1. Should there only be a single `var app1 = new Vue({ // The HTML element to attach to el: '#app',` Or might there be a case for multiple of these? I ask because it seems my entire html `<body>` will be encased in `<div id="app">`

2. In looking at @TotallyInformation complex home dashboard Vue app I see there are many Vue components. Even though they are outside of the initialized `new Vue()`Are those able to make use of the msg object because they share `dtOpts` like this?

```auto
data: function() { return {
        // For formatting dates and times
        dtOpts: {
            timeZone: 'Europe/London',
            weekday: 'short', month: 'short', day: 'numeric',
            hour: 'numeric', minute: 'numeric',
        },

```

Thanks for the help, I think I am close to understanding the setup and can now just have fun building what I want.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [29 October 2019 16:39 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/22 "2019-10-29T16:39:15Z")

</div>

> [@cuxcrider](#):
>
> Maybe it just depends on the final use case how to structure the object.

Yes, you've hit the nail on the head!

Indeed, you could also split the difference, at least when using bootstrap-vue, that is to use an object of objects instead on an array of objects.

e.g.

```auto
const devices = {
	"1a-0": {
			"serial": "1a",
			"channel": 0,
			"status": "running",
			"value": 100,
			"setpoint": 200
	},
	"1a-1": {
			"serial": "1a",
			"channel": 1,
			"status": "running",
			"value": 100,
			"setpoint": 200
	}
}

```

That still lets you drill down but still lets you pass the data without change to the table component in bootstrap-vue (the docs say it does anyway, I've not tested this particular data structure).

Another alternative is to send each device/serial object separately from NR and accumulate it into an array in the front-end instead.

So many options! 🥴

Clearly there are downsides to each of these approaches and, as you say, the "best" depends on how you are going to use the data.

> [@cuxcrider](#):
>
> Maybe I do not understand objects like I thought I did. I would have guessed my original object would be desirable because I could quickly drill down to a value of a specific channel on a specific board.

I don't know that any of us know them as well as we think we do! While your original object does indeed facilitate drill-down, it is also very complex.

When you move to the array format, you can no longer do `myobject["myindex"]` but have to do some kind of filter or lookup which personally I find a pain to do.

Using the intermediate form still lets you drill down a couple of levels quite easily with some text joins to create the index. If you need to turn it back into a pure array, that is also quite easy using `Object.values(myobject)` [mdn](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Object/values).

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/b/b803efdf76fe3cef0802d37a2cbaabc94db49cb5.png)

* * *

1. While you can certainly have \>1 Vue app, generally people don't. The only restriction is that each app **has** to only be defined by a single tag. So everything else has to exist as children of that tag. I believe that you can even make the app tag the `<html>` in which case, you can use Vue to control things in the head as well as the body. But again, unusual.

2. Eventually, I would move those component definitions into their own .vue files and either load them dynamically (using a helper library) or, for efficiency, by including a "build" stage using something like webpack to effectively "compile" each component and the main app into more efficient code.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [29 October 2019 16:39 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/23 "2019-10-29T16:39:17Z")

</div>

the main advantage is that it just works with the ui-table widget :-)... ok ok - I'll stop now !

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/5/5dd165a5a8125710e407eebb76be4b7bf01695be.png)

---

<div class="post-metadata">

**Author:** ![cuxcrider](https://avatars.discourse-cdn.com/v4/letter/c/58f4c7/32.png) [@cuxcrider](https://discourse.nodered.org/u/cuxcrider)\
**Post date:** [29 October 2019 16:55 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/24 "2019-10-29T16:55:52Z")

</div>

@dceejay haha fair enough.

My "dream" is to have a pretty robust app built similar to @TotallyInformation so I still think I'll need to go full custom.

---

<div class="post-metadata">

**Author:** ![cuxcrider](https://avatars.discourse-cdn.com/v4/letter/c/58f4c7/32.png) [@cuxcrider](https://discourse.nodered.org/u/cuxcrider)\
**Post date:** [14 November 2019 23:04 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/25 "2019-11-14T23:04:04Z")

</div>

Hi all,

I've come a long way. I basically have bootstrap-vue tables with sorting working and it's pretty awesome. I still owe you a basic demo flow so maybe someone else can use it as a starting point.

One final thing I'm not fully understanding with UIBuilder itself is how the UIBuilder node stores the index.html, index.js, etc. files. A couple times I somehow managed to delete my index.html file but I have no idea how. Obviously I did something wrong, just not sure what. One time it seemed like I rerouted an output from the UIBuilder and that reset my index file, but surely that was some sort of coincidence. Are the src files stored in my .node-red directory?

Thanks!

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [15 November 2019 00:46 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/26 "2019-11-15T00:46:26Z")

</div>

> [@cuxcrider](#):
>
> how the UIBuilder node stores the index.html, index.js, etc. files

No magic 😃

Everything is kept in the server's filing system. So you can use normal backup methods to take copies, you can even use git if you like.

Eventually, I'll build a simple git interface into uibuilder so that if an instance has git initialised, you can do simple commits, undo's and pushes.

> [@cuxcrider](#):
>
> A couple times I somehow managed to delete my index.html file but I have no idea how. Obviously I did something wrong, just not sure what.

It should be pretty robust, it isn't doing anything especially clever with the files and I've not had any issues myself either on Windows or the Pi.

There is a flag that, if you delete one of the index files, automatically copies the default template over. You might disable that so that it is a bit more obvious when the file gets deleted?

> [@cuxcrider](#):
>
> One time it seemed like I rerouted an output from the UIBuilder and that reset my index file, but surely that was some sort of coincidence

The only way that could happen is if you have a file-out node of some kind that writes to the file. Otherwise, the only thing that will change any of those files is the editor interface which works off a set of dedicated API's.

> [@cuxcrider](#):
>
> Are the src files stored in my .node-red directory

Yes, assuming that you are not using Node-RED's projects feature and are using the default Node-RED installation, the uibuilder root folder will be in `~/.node-red/uibuilder`. Then each instance of the uibuilder node creates a sub-folder named after the URL setting. Then that folder has the files in the `src` folder. So an instance with a URL called `fred` will have its files in `~/.node-red/uibuilder/fred/src/`. There is also a `dist` folder that will take preference if `index.html` exists in it. That is in case you want to have a build step for compiling things like Vue or transpiling with Babel.

Ah, that makes me wonder - have you changed the url setting at all? If you do, at the moment you get a new folder with the default template files. Your original files will still be available under the old name. Similarly, if you add a new instance with an old name, the old files will show up. I realise that this can be somewhat confusing and a proper rename feature is in the works.

* * *

I actually do most of my web development on my dev machine - so the "server" filing system is actually local. I tend to use VScode to edit the files as it is a lot more powerful than the ACE editor that Node-RED makes available. VScode now also has the ability to edit over SSH so you could use it with a Pi, etc if you prefer a full IDE instead of uibuilder's editor. I do use the uibuilder editor, typically for quick tweaks.

---

<div class="post-metadata">

**Author:** ![JVergara](https://avatars.discourse-cdn.com/v4/letter/j/85e7bf/32.png) [@JVergara](https://discourse.nodered.org/u/JVergara)\
**Post date:** [12 August 2020 10:36 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/27 "2020-08-12T10:36:00Z")

</div>

hi, i would like ask about this dashboard implementation. How it possilble to do a detailed table in a node-red app?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [12 August 2020 22:37 UTC](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173/28 "2020-08-12T22:37:26Z")

</div>

Hi, can I suggest that you start a new topic - it makes it a lot easier for people to help.

In the new topic, you will want to tell us a bit more about how you want things to work.

[Previous page](https://discourse.nodered.org/t/create-a-template-table-from-message-object/17173.md?page=1)
