Field in custom plugin not evaluating to correct value

Hi,
I am building a custom plugin and have a field called “record_id”. In the element editor window, I am setting that field to be the unique_id of my record which is stored the data of a group called “Group Record”.

So I have in my field:
record_id = Group Record’s record’s unique id

But when I log the value of the record_id to the console from inside the plugin, I’m getting a value of none.

I know my syntax is correct because when I log the group value of another group, I get the expected output.

The only caveat to this is that in the situation where it isn’t working, the Group Record’s data source is populated by a user action well after the page is loaded and the plugin element is loaded on page load whereas the other situation where it outputs the expected value, that group has it’s date loaded on page load. Could this have anything to do with it?

Please help. I am very stuck.
Thanks
Paul

I figured it out. Would not have been possible to help me without seeing my code. It was an issue with code being executed before the value had changed so I used a setTimeout function to loop until the value was there.

are you aware that the update function is invoked automatically every time the properties passed to the plugin change?
If your code can handle empty values there is no need for a waiting loop (which is a common source of bugs and infinite recursion)

1 Like

True that. Also @paul29, a Thing is its unique ID. Don’t send a text of the unique ID to your plugin… send the Thing itself.

Internally, you’ll .get() the unique ID when and if you need it (e.g., as when publishing a state).

1 Like

Thanks for your help.

I understand that but there is clearly a timing thing that is the result of the fact that I’m adding event listeners to buttons and it must be that that event listener was triggering before the updated field value came through which is why the setTimeout function created a band-aid. I understand it’s not great. Clearly my code needs to be refactored in order to properly wait for the new value. I may need to implement a mutation observer? Will need to play around.

Thanks for this keith.

I tried to do that but the list of available dynamic values are here and my Thing is not in the list so I figured this wasn’t doable.
image

You need a selector of “App Type”. Only the Bubble user can select this. Then you have a dynamic field whose type is set to that (let’s say the field is called type… you’ll have a dynamic field set to type “as type” to send the value). For an explicit and non minified version of this examine my “Fielder” plugin.

Ahhhh I see. Awesome. Ok thanks so much. I’ll definitely check out your plugin.

If you need to wait for an element to be present in the page the mutation observer it’s a better option than a waiting loop because you eliminate the risk of generating an infinite loop.

Agreed. Thanks for your help.

Hi Keith,
I’m trying to figure out how to do what you suggested of sending the thing itself. You said to look at your fielder plugin and looked for any value you had set to “app type” so I could follow what you did with the corresponding code but none of them are set to that.
Am I missing something?
Thanks,
Paul

Oh yeah. Apologies, that doesn’t actually need the app type as the field is set to “any thing with fields”. Sorry about that. Anyway, what I mean is like this in the plugins Fields section (or in the fields definition for an Action):

Thanks for the quick response. I understand that part. What I’m looking for is the corresponding code. You mentioned you would use the .get() method. So for your example in your screenshot, it would be properities.input_thing.get()

But what I’m after is how do I access the values associated with that thing? Does .get() return a list of all values? Does it just go inside the brackets?:
properities.input_thing.get(‘unique_id’)

Is that the syntax?

Thanks,
Paul

When you inspect the Bubble documentation for the Update or an Action code field, you’ll see that any “Thing” fields will be described like this (it’s pretty poorly formatted):

placeholder = {
     get: function(fieldName: String) - returns the value of a field for the object
     listProperties: function() - returns an array of the different fields you can access
}

What this is trying to tell us is that Things have a .get() and a .listProperties() method on them.

listProperties returns an array of strings that are the properties (fields) of the Thing. So in my example, placeholder.listProperties().

If you were to write the results of listProperties to the console, you can see what they are. They’ll include the names of any custom fields you’ve defined as well as various system fields including the unique ID which is in the property _id .

The get() method takes a string argument, the name of the field we want to get. So, to get the thing’s unique ID:

placeholder.get('_id')

And yeah none of this is properly documented so I can understand your confusion! (This is all very top of mind for me as I’ve been creating a conversation prompt that attempts to teach GPT4 everything it needs to know to at least stand a fighting chance of creating working Bubble plugins.)

1 Like

Awesome. This is super helpful. Thanks keith. Really appreciate this. Exactly what I needed.

yes, docs are terrible.

1 Like

Hi Keith,
One more quick question.

I am figuring this stuff out and I’m trying to access a related datatype. I have logged the result of to the console “placeholder.listProperties()” and it showed me that “roles_list_custom_gpt4_roles” is parameter of the field I’m interested in:

I then logged the result of that get request to the console and I see that it gives me two pointer values (which is what I see in the database tab)
image

My question is how do I get access to the data within those connected data types. I put in some text into one of the connected data types to search for it in the json response but it’s not there. My guess is I have to execute some javascript to access that data in the plugin.

Hopefully I explained myself well. Let me know if you need some clarification.
Thanks again in advance.
Paul

So, you’re passing some Thing to the plugin via a field of that Thing’s type. Now you’ve got access to that Thing and its properties. The property you’re interested in is itself a Bubble List (called Roles List). I’m not sure about this, but it looks to me like you’ve made the same error again.

In your database, your list of Roles should be a list of actual Roles, not a list of texts that are the unique IDs of some Roles.

If that List were a list of Roles, inside the plugin, when you List.get() the values, you will have an array of Bubble Thing objects that are the Roles themselves. These objects would then themselves have .listProperties() and .get() on them and you could fetch the values of those fields.

But it looks to me like the way you’ve got your database set up, you’re just storing texts, which is not helpful, obviously.

I dont’ think I have it setup improperly. Here is the datatype that I’m passing to my plugin
image
On the above, when I run listProperties() I get:
[“roles_list_custom_gpt4_roles”,“Created By”,“Slug”,“Created Date”,“Modified Date”,“_id”]

And here is the datatype that I’m trying to access:
image
and then when I do .get(“roles_list_custom_gpt4_roles”) I get a ton of data (this is just a snippet):

I searched through the output of the .get() method for a value of “content” and it’s not there

OK good to see that’s set up properly!

Don’t be doing JSON.stringify() on the output. This will just confuse you because what you really have here is an object with some methods on it. If you wanna see what any of these things are, just literally write the thing to the console. What you’re seeing is a serialized representation of the object and we don’t care about any of that. We care about its methods.

So, you’ve got this formated_content (god I hate typos) property that is a GPT4 Prompt object:

var prompt = props.formated_content 
var roles_list = prompt.get('roles_list_custom_gpt4_roles') // I assume this will be a List object - it'll have a get method on it
console.log('Roles list before get: ', roles_list)
roles_list = roles_list.get(0, List.length()) // get the entire List, now you'll have an array of Things
console.log('Roles list after get: ', roles_list)

You’ll see that each of the items there is a Thing. They will have the .get() and .listProperties() methods on them and one of those properties will be ‘_id’ (this is how you can recognize a Thing).

Take one of the objects and do .listProperties() on it. Then you’ll know the field names and you can .get() any of them you want:

var first_role = roles_list[0]
console.log('A Role has these properties: ', first_role.listProperties())

Unreal. Couldn’t be more helpful. Thanks so much Keith. (also I fixed the typo. You can sleep easy now)

1 Like