Advanced Tasker: Dealing with empty variables in scene menus
Disclaimer: Advanced Tasker is a series of Tasker articles that go beyond the beginner’s guide, and that’s aimed at those who have full control over everything covered in the guide. In this article series, step by step instructions will not be provided, there won’t be any downloadable files, and questions that belong in the beginner’s guide will not be answered. The aim of these articles is to discuss ideas that can be implemented in many different ways, in many different projects- and that requires the ability to create things from scratch, not by following step by step guides.
I’ve previously talked about how using single variables instead of arrays can speed up the population of Menu scene elements drastically.
That does however bring up another problem. Unlike arrays, variable’s aren’t ever empty. If they are empty, they contain their own name, and if you write a space to them to make them appear empty, well then they contain a space. That means that an entry with either the variable name or a space will show in your Menu element, and if you have static icons for each list item like I do, even the instance with the space will be visible- and it will be there in any case.
There’s a method to deal with this, and it’s luckily fairly straight forward. First off, you need to make sure a variable is never empty to where it contains its own name, but rather always contains a single space when “empty”. This just means you use Variable Set with a space instead of Variable Clear, and you can even use a single Variable Set action to set it to a space with an If condition for it matching its own name before you launch your scene, just in case.
When that’s done, you need to start launching your scenes like this:
Here’s what happens in the above screenshot:
- First it creates the scene without displaying it, allowing for manipulation of scene elements
- Then it uses Element Visibility to make sure the Menu element is visible, but only if the variable used in that element, %Gtodo, is at least two characters long
- Then it uses another Element Visibility to hide the Menu element if the variable doesn’t contain at least two characters
- Finally, it displays the scene
In other words, every time the scene launches, it checks to see if the variable used in the Menu element is more than a single character long. If it’s not, it’s likely because it contains only a single space, and then it just hides the entire Menu element. Problem solved! At least if your scene only displays the info, so that you launch it every time there data changes. Things are a bit more complicated if you’re…
Adding to the variable from within the scene
In that case this works, but it might require that you use Element Visibility actions elsewhere too, depending on your project. My todo list, for instance, has options to add to the lists in the scene, while the scene is active. But, if the list is empty, the entire Menu is invisible, which means that if I just add to the variable, it won’t show unless I also include the Element Visibility action to re-enable the Menu element after I add something to the variable.
I know this sounds complicated, but trust me, this method is much, much faster than the easy way out, which is to just live with the delay caused by global arrays. My todo list project has gone through multiple rewrites, and it currently uses this method for populating the list, and I can assure you that it’s much faster than using a global array. It’s more complicated, yes, but it’s all about adding a few more actions when you create the project so that it works better in the long run. I’ve used this for many months now, and it works perfectly.
On a related note, I should add that using a variable instead of an array does mean you need to compensate a bit when you’re actually editing the variable as well. For instance, you need to remember that Variable Split to convert a variable to an array only works if there’s at least two items in the variable. This is because you split the variable by a comma, and that comma is only there if there’s more than one item. A simple If condition to check if the variable actually contains a comma is an easy fix for this.
Another take on adding info to a variable is to simply skip arrays altogether. Using Variable Search Replace and Variable Set you can do a lot of what arrays are good at with variables directly, such as appending info and removing something out from the middle of them. Here’s a couple of examples from my todo list project:
The above screenshot shows a method for adding something to the end of a variable. What you don’t see from the above is that the second Variable Set has Append enabled, while the first one doesn’t. If %Gtodo doesn’t match ++, it means it’s a single character, likely a space, and it’s considered empty. In that case, it replaces the value of the variable with the data that is added, %itemtoadd, and gets rid of the space in the process. The alternative situation is if %Gtodo is longer than two characters, which means it’s not empty. In that case, it appends a comma followed by the new data, %itemtoadd, to the variable.
This means that if %Gtodo has a value “apples,bananas”, and %itemtoadd is “pears”, the resulting value of %Gtodo will be “apples,bananas,pears”. When fed as a single variable into a Menu element, it will list everything separated by a comma individually.
This screenshot on the other hand shows a way to actually edit an entry in the Menu element. This is part of a long tap task for my todo list scene, meaning that I can press and hold an item to edit it. The variable %tap_label is a built-in variable that contains the data from the Menu item you clicked, meaning that if the item you clicked was “bananas”, %tap_label will be “bananas”.
To make this work as an edit feature, it first pops up a Variable Query, where %tap_label is used to populate the text field with the info you’re editing. Once done, it performs a Variable Search Replace, replacing the old %tap_label with the info from the Variable Query.
The downside of this is that unlike doing this with an Array, you can’t stop it from replacing it anywhere it finds it. So if %tap_label is present several places, it will replace all of them. An example would be if the first item on the list is “apple”, and the second is “apple pie”. Editing the first item to “orange” would leave the list saying “orange” and “orange pie”.
These are just two examples of how to deal with the fallout from using a variable instead of a global array. The reason why I haven’t covered my last few versions of the todo list project in detail is quite simply that there’s a ton of things like this in there, in other words complex systems designed to work around issues in Tasker. It’s ironic, but even though it’s way more complicated, it’s also way, way faster.