Custom javascript to sort records from Firebase

I’m experimenting with the custom javascript flow node. I download data from Firebase and I want to sort by date. Here is the Javascript code that is not working:

const objs = inputs.input1;    // bound to data variable 'dat'
objs.sort((a,b) => Date.parse(b.fields.date.stringValue) - Date.parse(a.fields.date.stringValue));
return [ 0, { result: objs } ];

I download the data collection from Firebase into the data variable dat. So I bind inputs.input1 to dat.

I output the sorted object (objs) on outputs.output1. I set the output to a page variable with the same schema as the data so I can use it. I’ve looked at the output in the debugger and also examined a “stringified” version of the output and it appears to have the correct structure, but it is not sorted.

Here is the structure of the data that I download from Firebase:

[
    {
        "name": "projects/<projectID>/databases/(default)/documents/<collectionName>/<recordID>",
        "fields": {
            "total": {
                "integerValue": "119"
            },
            "active": {
                "booleanValue": true
            },
            "name": {
                "stringValue": "Peter"
            },
            "date": {
                "stringValue": "08-24-2022"
            }
        },
        "createTime": "2022-08-24T20:44:19.770997Z",
        "updateTime": "2022-08-25T14:45:24.994049Z"
    }]

I’m pretty sure the javascript is “almost right” - but something is amiss. I’ve looked for answers in this forum, StackOverflow, and various javascript websites (like W3Schools).

I’d appreciate any insight into why this javascript does not sort my data.

========================= Edit ============================
I found the solution. I am not deleting this post because someone else might find it useful.

I discovered that the Date.parse() function only works reliably with ISO formatted date strings (mine are not - they are in the MM-DD-YYYY format). I found a function on StackOverflow that takes a date in virtually any format and converts it to an ISO formatted date. I then fed the result of that function to the sort routine and it works.

Just a quick question. Why use custom javascript for rearranging objects in a list instead of using the built in formulas?

I mean rearranging by date could in fact be as simple as this:

ORDER(outputs["Get record collection"].records, "date", "asc")

As I see that Your date is not in the regular format, you would have needed a formula like this:

ORDER(MAP(outputs["Get record collection"].records, SET_KEY(item, "date", (SPLIT(item.date, "-")[2]+"-"+SPLIT(item.date, "-")[0]+"-"+SPLIT(item.date, "-")[1])), "date", "asc")

I know I know, it seems to be overwhelming, but it basically does the same thing as Your custom js… :sweat_smile:

1 Like

Well @Mihaly_Toth that is kind of a long story. But, since you asked:

I had a great deal of trouble with the GROUP() function. I wanted to group by user name and calculate a sum for each group. I could not get that to work with an Appgyver formula. I posted a question in this forum about it but did not get a solution. I started thinking about writing a Javascript function to do that job.

In pursuit of that end, I created a javascript function to filter the data and then another one to calculate a sum. I also wanted to sort the data by date, so I started working on that.

In the mean time, I figured out how to do filter and sort in Appgyver:

ORDER<date>(SELECT(data.Dat,IF(item.fields.name.stringValue == appVars.avLoggedInUser,true, false)),date.fields.date.stringValue,"desc")

But I still have not yet succeeded in using the GROUP() function to group the records. But I will now be able to combine all of these to write a custom javascript junction that does it all.

I think the bottom line is that the formula just got too complicated for me to sort out all of the issues.

But, you may be able to answer a question for me. I stumbled across my Appgyver formula solution using ORDER() by looking at the help. I found this odd notation ORDER<item>( ... ). I have never seen that angle bracket notation in programming before (obviously I’ve seen it in HTML, etc). I don’t understand it. I just know that it works in my case. What does it tell the ORDER() function that date.fields.date.stringValue does not already tell it? Is that a JavaScript thing? (I’ve Googled “programming angle brackets” but I just get a million hits for hardware stores!!) Can you explain to me what this angle bracket notation means and in what circumstances it is used?

This <item> is insanely helpful if you have several nested formulas, like MAP(SELECT(ORDER(SET_KEY())))
What it does is that it creates an “alias” for the current object for that formula.

So let’s say you want to go through each value in a filtered list. For this we would use a MAP and a SELECT formula.
First we filter the list with the SELECT() formula, then go through each item with the MAP()
It would look like this:

MAP<filtered>(SELECT<fullList>(data.list, fullList.filter==true), {name: filtered.name, filter: filtered.filter})

So the idea of the <> here is to simplify and clarify complex formulas.

Regarding the GROUP() question, I’ll try to get through that thread in a few minutes. :smiley:

OK. Thank you!! Good explanation and good example!!! :smiley:

@Mihaly_Toth Can you explain this example of the use of the angle bracket notation in the GROUP() function help?

GROUP<product, index, category, products>(allProducts, product.category, { category: category, count: COUNT(products) })

There are multiple aliases within the angle brackets. Are they assigned in the order in which they are encountered in the arguments? (probably not, since the index alias is not even used).

  • product is apparently an alias for a single product in the list of products.
  • index is ??? - I assume this could be a zero based index for each of the items in the list, but it does not appear to be used in the GROUP() function example
  • I assume category is an alias for product.category.
  • And I assume products is an alias for allProducts.

Where can I find some documentation on this?