Forum Documentation Showcase Pricing Learn more

Toolbox plugin - collection of utility elements


#82

List Item Expression’s input needs to be given a list (that is recognised by Bubble as a list), which is what you are aiming to produce …

At the moment, a better fit is the Expression element, just need to split it with something like:

[["a", "b"], ["c", "d"]].map(JSON.stringify)

There is something better in the pipeline :wink:


#83

@mariob Looks like a problem with the automatic minify that happens when a plugin is published. I’ve raised a bug report to Bubble, and left the example app broken to demonstrate the problem. Hopefully no other plugins are affected.

The other elements seem to work okay, so its okay to use v1.0.0 if you don’t need List Item Expression.


#84

Hi @mishav, could you please take a look at my post?

Thanks
Mario


#85

v1.0.1 New Version

  • List Item Expression bugfix from issue introduced in v1.0.0

  • List Item Expression additional functions item( ) and chainable lookup( ).

These can be used for more complex operations, like getting access to list of things in a field.

item() refers to the current list item, it isn’t useful on its own.
item().lookup("Name") returns the Name field of the item.
item().lookup("Components")[0].lookup("Component Name") First component’s name

Remember to refresh the app editor after upgrading a plugin.


#86

Does the List Item Expression support the new “groupings” list type?
When I set a repeating group to a list and process it into a “groupings” the LIE doesn’t see it anymore.
The LIE doesn’t have a “groupings” option in the type pulldown but nothing else does either.


#87

Is there a way to access the previous and/or next item in the List Item Expression?
Like item (x) - item (x+1) = y so there’s a new list of y’s


#88

Not yet, thanks for the tip, I’ll have a look at supporting that too.

Its currently setup to run the expression for each item, in isolation from the other items. I can see why you’d want to do this.

One way to do this is with the Expression element, taking a list of numbers and manipulating the value based on previous (or next) list item …

Map runs the function for each item in the list, and generates a new list.

[Search for Book’s numtype].map(
function(val,pos,list){
return pos > 0 ? list[pos-1] - val : val;
})

App editor example here


[New Feature] Grouping and Aggregating Data
#89

Thank you. Based on a list of logged foods I can calculate time fasting as the time between foods.

I had to convert the dates into UNIX milliseconds. Does the math work on dates? it would be nice to keep the date and the fasting period together in a list so i can chart longest fast each day.

Or, given the list of dates, can i convert them into UNIX milliseconds for the purposes of the calculation (rather than converting into a list of numbers first) and return both the date and the fasting period? Bubble doesn’t handle arrays very well. That list format might have to be a grouping?


#90

Can I generate a list of database things (not text, number, or date)?

I’m trying to chart the result of calculating fasting times (time between food records).

I do a search for thing:A with field:datetime, convert it into a list of numbers by extracting the UNIX ms, then feed that into the map function per your example. I get a list of numbers that are the milliseconds between each log.

But, ironically, I can’t graph a list of numbers. I know, right? And once it’s a list of numbers I can’t convert it back into a list of things. With the line/barchart I can only graph a list of some thing from the database.

I couldn’t find an example where a toolbox element was used to generate a list of database things even though the database things appear in the dropdown. I figured if I could output a temporary list the chart element recognizes I could graph the results.


#91

So I was able to solve part of my problem. Sharing here in case it helps someone else.

Put this into an expression element:

[ *search for thing's datetime:extract UNIX* ].map(
  function(val,pos,list){
    return pos > 0 ? round((list[pos-1] - val) / 1000 / 60 / 60, 1): 0;
}).sort(function(a,b){return b-a}).slice(0,7);

function round(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
  1. get a list of numbers
  2. use map to generate a list of deltas between the previous numbers (plus one 0 value) converted into hours with one decimal place using the round function
  3. sort the new list descending
  4. throw away all but the first 7 items in the sorted list

This gives me the 7 longest fasting periods from the last 7 days (the original search covers 7 days). Then I average the 7 fasting times together and display the average fasting time for the last week.

Haven’t figured out how to graph the times yet.


#92

That’s not possible, even though yes it’d be nice! You might be able to generate a list of date ranges, each date range is a list of two dates …

Possibly with a date range, not sure how you’d process the period if its being in a date form though …

The usual approach is to give the graph multiple lists, one for each dimension or axis or property, where the same item number means the same point to be graphed.

If you send the data from javascript into a non-Bubble javascript chart, then you have more control, at the expense of lots more coding.

Nice!

If inside the map function you returned an object containing the original value, as well as the delta, you can still sort the list of obects by its delta property. Then either:

a) return to Bubble a list of date ranges, or

b) return the list of deltas, and send the matching list of dates to another element, like JavascriptToBubble.

I should probably read your use case during daylight hours to understand it more, haha.

Good luck!


#93

Yeah, I already setup a totally different server I’m copying the data over to so I can analyze and chart it properly. My app pulls completed charts back from a custom API.

What I’m running into is that Bubble doesn’t do arrays, loops, or recursion…it barely does math at all. So I can’t do any analysis or reporting of the data people are logging in Bubble itself.

Bubble adding the group/aggregate function allows me to do a few calculations, like total sleep per day, and now fasting per day. So that’s nice.

But I can’t do something like calculate macros because I have to do math on the number from one thing combined with the number from a linked thing. Like if someone logs “100g eggs” I need to reach into the “egg” preset to get “protein 50g per 100g”. Even if I could get the math to work I can’t graph it because Bubble only graphs database things, not raw numbers.

The CRUD functions are so good I keep trying to stay in the platform.


#94

Umm… How DO you return a date range? I’ve tried a couple of different methods (one using moment-range and another just making my range a two element array) but Toolbox throws an error when I try to send this to a JavaScript to bubble element.

I get:

The plugin Toolbox threw the following error: Error: Expected a date range, but got a object (original data: ["2018-08-06T07:00:00.000Z","2018-08-10T07:00:00.000Z"])

^^^ this is what happens if I try to create the range as:

var range = [startDate, endDate];

If I instead to var range = moment.range(startDate, endDate); … I get:

The plugin Toolbox threw the following error: Error: Expected a date range, but got a object (original data: {"start":"2018-08-06T07:00:00.000Z","end":"2018-08-10T07:00:00.000Z"})

So, it seems that neither “obvious” approach isn’t liked by Bubble… What the heck is Bubble expecting? I can’t figure it out…


#95

An array of two javascript dates, if they’re moment.js objects they’ll need converting.

var d1 = new Date(2010,1,1);
var d2 = new Date();
bubble_fn_daterange([d1, d2])

sample edit page


#96

Gracias!


#97

@mishav, this is correct. Thank you! ANOTHER stupid Toolbox question for you:

Can Expressions (the Expression element) take advantage of loaded scripts? I have an HTML element on my page which loads scripts (like moment, moment-timezone, etc.). I can call moment() functions in a RUN JAVASCRIPT element just fine, but I cannot seem to call them in an expression.

The debugger throws an error like:

“The plugin Toolbox threw the following error: ReferenceError: moment is not defined
at getDaysInMonth (eval at (eval at g.create_code (https://dhtiece9044ep.cloudfront.net/package/run_debug_js/ade098cad2428d316eb67527abf239f07f2a86ac3be6db2b5e7f34bc4c9e0e6f/xfalse/x3:101:12521)), :4:1)”

But the scripts are already included in the page… why can’t Expression “see” them?

Thx,
K


#98

If a script is loaded on the page, it won’t be finished loading when the first update() happens on elements.

The trick is to have the expression check for page loaded, which calls update() on the element again when page loaded changes from no to yes.

image

I’ve put up an example with console logging to show the sequence of what happens.

example editor
example runtime


#99

Dude. Thanks for that. I was wondering why I see Expression evaluating twice before anything else happens.


#100

@keith Another way to do the same thing is set a conditional for page loaded …

Pro: cleaner expression
Con: easy to not notice the conditional tab

image image


#101

Brilliant. Thanks for that!