How to access a nested list of objects in the plugin code without making an external API call?

I am working on an application where I am forced to create my plugin to personalize the return of data from the API.here is the data available via proprieties.all_thing


the purpose of my plugin is to be able to retrieve only the essential data via this api route. the problem is that here I do not have the data directly but rather the id which leads to the data. So far I have used the get_object_from_id() function to retrieve an object from the database using its id, but the problem is that when I do this the API takes too long to return the data.
the bubble team advised me to use this function to recover the data:
function fetch_list_of_things = (list) =>
list.get(0, list.length()).map(entry =>
entry.listProperties().reduce((object, property) => {
object[property] = entry.get(property)
}, {})
)
.

my problem is to know how I can use this function to retrieve all the quizzes that are available in the array questions_list_custom_question present on the first first image.
need help please.

Woah! You’re doing some complex things here.

Why don’t you just do the API call from a server side action? ( a Node JS API call).

This would be x 1000 times easier, no?

We did that already and it was too slow. It took more than 5 sec to generate the JSON!

Hmm. Can’t help you there, I don’t think it’s worth it to try and work around this.

there should be a way to access a nested list of things natively without having to make an external API call, right?

no issue when accessing a nested object with get().

can you elaborate please? how to use node js to query the database and retrieve the data …

You don’t need node JS to query your backend. you can use fetch and do it client-side

It looks like you need to flatten your Jason array. Bubble doesn’t do well with handling complex jsons, period.

1 Like

How to flatten your JSON array from plugin code? Basically, I have list of object ids. I would like to access the objects.

You didn’t hear this from me (and you know how these undocumented things go, they can be gone without notice…)

But you may want to take a look at this gem:
var objs = get_objects_from_ids(chunk);

   for (let i = 0; i < ids.length; i += chunkSize) {
        	var chunk = ids.slice(i, i + chunkSize);
	var objs = get_objects_from_ids(chunk);  }

Note: The reason this is in a loop is because it can still timeout fetching the data, so if you loop over chunks of the ids then you reduce the risk of timeout (with larger datasets).

1 Like

It’s very unclear to me what the OP is actually trying to accomplish here and it seems all sorts of wrong. BUT I want to make something very clear to anyone who might stumble upon this thread:

There is no reason, when building one’s own plugin – NO REASON AT ALL – to use get_object_from_id(). If you are building your own plugin and using this, you are doin’ it rong.

The only use case for get_object_from_id()is if you are duplicating Mishav’s “Server Script” plugin idea (whereby they let a Bubble user enter some code which then gets eval’ed in the SSA). Because there’s no way of sending an actual Thing from the text field for the code, this function would be necessary for taking unique ID’s (which can be put into the text field) and reconstituting them into Things. And I suspect Misha probably specifically requested this function to make the Server Script plugin viable. (Although there is probably some similar function used by Bubble in rehydration.)

NOW, if you are building a plugin for yourself or for other Bubble users, you DO NOT SEND THINGS TO THE PLUGIN AS UID’S - you send them as the Things themselves!

For example, as in List Popper:

And now, in your plugin, “data_source” will be a Bubble List object which you can then turn into a JavaScript array using its .get() method. If the type of that list is some Thing, the contents of that array will be an array of other Bubble objects that are Things. It has a listProperties() method for inspecting what fields (properties) the Thing has and a .get() method on it to get the field values.

When we send Things back to Bubble (from an SSA) we do in fact represent them as their unique ID’s, but we do not send that string or array of strings to a text type output/exposed state, we send that to a state of type the Thing type. And when Bubble receives this it rehydrates those UID’s back into their constituent Thing objects.

Again, as in List Popper:

tl;dr get_object_from_id() is not for use in “proper” plugins

EDIT: But that one-line reducer for getting the first level of properties from a list of things is pretty :fire:, Bubble support! There is a bug in it, though, it means to be like this:

var result = list.get(0, list.length()).map(item => item.listProperties().reduce((object, property) => (object[property] = item.get(property), object), {}))

result will be an array of objects that are the Things, where we have get()'ed the first level of their properties, like so:

(The error was that the reducer in their jotted down code was just object[property] = item.get(property), but while that does something (assigns the value of the property to object), an assignment statement returns undefined, so we need to return (to the reducer) the updated object, hence: (object[property] = item.get(property), object) in my modified version above.)

2 Likes

@keith Generally speaking yes, but there are some (probably very limited) specific ssa use cases that make these (however wrong and incorrect) undocumented functions highly useful. What would be nice is if they were proper documented functions and we could use them reliably without worrying about them being depreciated.

@keith

We got all that and we were using get_object_from_id(). which is not efficient at all! You did you tell us what we should have done instead to access nested list of objects.

That is where we need help.

Regards,

@keith

Let say I have this database structure. We are having trouble to retrieve the list of rows in order to build the JSON string. Here is where we need help.

col

name text
row row
rows list of rows

row

name text

col’s rows is [“1668091578070x798078500567274100”,“1668091584847x884855879522720800”]
How to retrieve the objects natively?

Assuming this:

{
“_pointer”:{
“_source”:{
“name_text”:“simo”,
“row_custom_row”:“1668106093889x724570050708183600”,
“rows_list_custom_row”:[
“1668091578070x798078500567274100”,
“1668091584847x884855879522720800”
],
“Created By”:“admin_user_quizetc_test”,
“Created Date”:“2022-11-10T14:47:10.034Z”,
“Modified Date”:“2022-11-10T18:48:30.567Z”,
“_id”:“1668091630034x958665882954450800”,
“_type”:“custom.col”
},
“_id”:“1668091630034x958665882954450800”,
“_type”:“custom.col”
}
}

I can retrieve row_custom_row no problem but I am having issue to retrieve rows_list_custom_row objects

Umm… I did tell you.

Also, go look at my edit to that first reply where I show how one might use that code from Bubble support (the provided code was not 100% correct and I fixed that).

Obviously you could extend this to do other levels deeper.

@keith

the code below produced the JSON below but we can’t still access the object list.

var result = thingsList.get(0, thingsList.length()).map(item => item.listProperties().reduce((object, property) => (object[property] = item.get(property), object), {}));

@keith We have 3 nested hierarchy: quizzes → questions → options. So we need the code that would reduced 3 levels deeper. :pray:

Look: when you .get() a list, you will then have an array of some datatype.

If that datatype is a Thing, you will then have an array of Bubble objects (Things) which have the listProperties and get methods on them.

The properties on a Thing may themselves be Things or Lists that themselves may resolve to arrays of Things.

So, you can walk this as deep as you want before getting rid of the original objects.

But you should not in general do it recursively as consider that a Bubble thing could have a field of the same type of thing that could in fact have a reference to the higher-level thing itself on it and your code will just loop infinitely.