08-04-2022 17:51 - edited 08-04-2022 17:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-04-2022 17:51 - edited 08-04-2022 17:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi,
I am building an app where I fetch a list of items from a web server and display them on the app using Virtual tile list. The fetch part is working fine. I am having trouble with virtual tile list. Nothing shows up on the Fitbit OS Simulator when I start up the app. I am using versa 3 (Atlas) in Fitbit OS Simulator.
Here is the code:
resources/widget.defs
<svg>
<defs>
<link rel="stylesheet" href="styles.css" />
<link rel="import" href="/mnt/sysassets/system_widget.defs" />
<link rel="import" href="/mnt/sysassets/widgets/baseview_widget.defs" />
<link rel="import" href="/mnt/sysassets/widgets/scrollbar.defs" />
<link rel="import" href="/mnt/sysassets/widgets/tile_list_widget.defs" />
<symbol id="my-header" href="#tile-list-header" class="list-item header">
<text id="text">HEADER</text>
<rect class="line" />
</symbol>
<symbol id="my-item" href="#tile-list-item" class="list-item" display="none">
<rect class="bg" />
<text id="text" text-length="32"/>
<rect class="line" />
<rect id="touch" pointer-events="all" />
</symbol>
</defs>
</svg>
And this is my app/index.js
import * as messaging from "messaging";
import { FitSagaUI } from "./ui.js";
let ui = new FitSagaUI();
// Listen for the onopen event
messaging.peerSocket.onopen = function() {
console.log("Peer socket opened");
ui.updateUI("loading");
messaging.peerSocket.send("Hi!");
}
// Listen for the onmessage event
messaging.peerSocket.onmessage = function(evt) {
ui.updateUI("loaded", evt.data);
}
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
// Handle any errors
ui.updateUI("error");
}
FitSagaUI.prototype.updateUI = function(state, challengeNames) {
if (state === "loaded") {
setupList(challengeNames);
}
}
function setupList(challenges) {
console.log("challenges: " + challenges);
let myList = document.getElementById("myList");
let NUM_ELEMS = challenges.length;
myList.delegate = {
getTileInfo: (index) => {
return {
type: "my-pool",
value: challenges[index],
index: index
};
},
configureTile: (tile, info) => {
if (info.type == "my-pool") {
tile.getElementById("text").text = `${info.value} ${info.index}`;
let touch = tile.getElementById("touch");
touch.onclick = function(evt) {
console.log(`touched: ${info.index}`);
};
}
}
};
And here is my resources/index.view file
<svg class="background">
<use id="myList" href="#tile-list">
<var id="virtual" value="1" />
<var id="reorder-enabled" value="0"/>
<var id="peek-enabled" value="0"/>
<var id="separator-height-bottom" value="2" />
<use id="my-pool" href="#tile-list-pool">
<use id="my-pool[0]" href="#my-item" />
<use id="my-pool[1]" href="#my-item" />
<use id="my-pool[2]" href="#my-item" />
<use id="my-pool[3]" href="#my-item" />
<use id="my-pool[4]" href="#my-item" />
<use id="my-pool[5]" href="#my-item" />
<use id="my-pool[6]" href="#my-item" />
<use id="my-pool[7]" href="#my-item" />
<use id="my-pool[8]" href="#my-item" />
<use id="my-pool[9]" href="#my-item" />
<use id="my-pool[10]" href="#my-item" />
<use id="my-pool[11]" href="#my-item" />
<use id="my-pool[12]" href="#my-item" />
<use id="my-pool[13]" href="#my-item" />
<use id="my-pool[14]" href="#my-item" />
</use>
</use>
</svg>
What am I doing wrong? I copied the exact code that I found in the docs. See the image below for what I am getting
Answered! Go to the Best Answer.

Accepted Solutions
08-05-2022 14:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-05-2022 14:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I found the issue. I forgot to add css for all the elements. That is why they didn't show up
.list-item {
height: 112;
}
.list-item text {
fill: "white";
x: 50%;
text-anchor: middle;
font-size: 24;
}
.line {
height: 6;
width: 100%;
fill: #222222;
y: 100%-6;
}
.header text {
font-weight: bold;
fill: fb-cyan;
font-size: 30;
}
.footer text {
font-weight: bold;
fill: fb-green;
font-size: 30;
}
08-04-2022 20:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


08-04-2022 20:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I didn't study closely, but try setting myList.length. I think this needs to be done after other list config, as it seems to trigger a redisplay.
Gondwana Software

08-05-2022 09:27
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-05-2022 09:27
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I have tried setting it, but still doesn't work.
function setupList(challenges) {
console.log("challenges: " + challenges);
let myList = document.getElementById("myList");
let NUM_ELEMS = challenges.length;
myList.delegate = {
getTileInfo: (index) => {
return {
type: "my-pool",
value: challenges[index],
index: index
};
},
configureTile: (tile, info) => {
if (info.type == "my-pool") {
tile.getElementById("text").text = `${info.value} ${info.index}`;
let touch = tile.getElementById("touch");
touch.onclick = function(evt) {
console.log(`touched: ${info.index}`);
};
}
}
};
// length must be set AFTER delegate
myList.length = NUM_ELEMS;
}

08-05-2022 13:57
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


08-05-2022 13:57
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Does the console.log at the start of setupList() display a list of strings?
If so, try adding some console.log lines for debugging in getTileInfo and configureTile.
Gondwana Software

08-05-2022 14:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-05-2022 14:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Yes, it does. I also added console.log statement to the if block inside configureTile. The console.log statements print correctly.
configureTile: (tile, info) => {
if (info.type == "my-pool") {
tile.getElementById("text").text = `${info.value} ${info.index}`;
console.log("title text: " + tile.getElementById("text").text);
let touch = tile.getElementById("touch");
touch.onclick = function(evt) {
console.log(`touched: ${info.index}`);
};
}
}
I am wondering if something is wrong with my widget.defs file.

08-05-2022 14:18
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


08-05-2022 14:18
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I had a quick skim of your widget.defs and it seemed okay.
I'm currently working on an app that uses VTL. It does work but can be finicky. I'll load up your code soon and see if I can get it to work.
In the meantime, maybe verify that you've got appropriate CSS for the relevant elements and CSS classes in your code. You may need to use some of the CSS from the non-virtual example in Fitbit's documentation.
Gondwana Software

08-05-2022 14:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-05-2022 14:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I found the issue. I forgot to add css for all the elements. That is why they didn't show up
.list-item {
height: 112;
}
.list-item text {
fill: "white";
x: 50%;
text-anchor: middle;
font-size: 24;
}
.line {
height: 6;
width: 100%;
fill: #222222;
y: 100%-6;
}
.header text {
font-weight: bold;
fill: fb-cyan;
font-size: 30;
}
.footer text {
font-weight: bold;
fill: fb-green;
font-size: 30;
}
