Implementing App Code into Plugin Editor

Hi, I’m trying to implement code that works fine on a staging server (one js file, use classes). I can see that apps have the code split out into function groups. Any tips on moving code from one js file to splitting out into bubble?

1 Like

I would love to see a bubble course on this. Moving from a single js file to using separate functions was hard to adapt to at first but is no problem now.

Here are some helper hints

Create inputs for the main element or for each event action separately. Think of these as local data for either the main element for for its receiving element action as these get their own input fields. Acces them by calling properties.<fieldName>

Pass that data around using the below

You can create global variables/functions by calling them at instance.data.<insertVariableNameHere>

You can append html elements to the main html body by calling instance.canvas.append('<div id="div1">text</div>)

Also, if you are calling data outside the bubblesphere Context.async Will be your friend. I learned this when incorporating Firebase into a project.

Publish states by first creating the state and then calling in your function instance.publishState("stateName", data)

Trigger element events by creating the event and calling in your function instance.triggerEvent("eventName")

3 Likes

That’s really helpful. Thanks

Hi Jared, how did you approach breaking up the js into smaller pieces. Currently broken up the code into function groups and now looking at the best way to pull it all together.

Could you say more about Context.async @jared.gibb - I haven’t used before.
What was the use case and how did you use it?
Thanks

1 Like

@edwardbutcher
for async i’d start reading here
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

basically, any time you need to do an operation that requires outside data (such a call to firebase or other API service) and that is not immediately returned, you would want your code to wait for a response.

javascript likes to run sequentially and fast. it doesn’t know to wait unless you till it to. therefore, if you dont tell the code to wait which is what async/await if for, you’ll end up working with null/empty variables.

take this example of a call to firebase to get some data.

        let list = context.async(async callback => {
        try {
            const snapshot = await admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
            const element = snapshot.val()
            let list = []
            for (key in element) {
                list.push(element[key].Name)
            };
            callback(null, list);
        } catch (err) {
            callback(err);
        }
    })

    
    return {  "data": list }

i set list = to the context.async.
this lets the compiler know to wait until it gets a response.
the response that it waits on comes from the signaled await.
the code pauses when snapshot is to be assigned a value until data is retuned , then it continues.

so in order, the entire script pauses at the async and waits for any awaits before going on to the next line of code instead of executing without waiting for return data

also, im no javascript expert. just someone trying to get by int his coding world

so if we did this

    let snapshot = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
    const element = snapshot.val()
    let list = []
            for (key in element) {
                list.push(element[key].Name)
            };

    return {
        "data": list
    }

list comes back empty because the compliler didnt wait on the returned data.

@cho04
I do this based upon the different actions that a script might need to complete. For example, i have coded a signature padd. the pad has a few functions. so i split it up based on this unless the controlling element is actually coded in the HTML that i added during initialization (i.e using an HTML button instead of a Bubble button).

it needs to initialize on page load
output a signature image to a state as an action
clear and reset the pad as an action
and clear the state as an action

4 Likes

So if I have a visual element (map) that has a button outside the element. What would the steps be within plugin-editor to run a function within the element?

depends.

id start with assinging the map element to an instance.data.variable

here’s one example. this image is in the initialize code. it’s messy. so any other time i need this image i call instance.data.pic regardless if im working in the update code, initialize, or any other element action

    instance.data.pic =  "data:image/png;base64, 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"

this is how you ‘pass’ around the HTML element (or any other data) between plugin actions

1 Like

The map element is assigned a variable instance. canvas.append(mapid), is that what you mean?

Well there’s a couple ways to do it.

You’ve got something like

        let box = '<div id=“something”></div>'
        Instance.canvas.append(box)

You could reference in another element that div like this


let newBox = document.getElementById(“something”  + properties.elementID)

Then you could do that in each element which can be annoying sometimes if you are also appending an elementID dynamically. So

Instead I’d use this when I instantiate the element


Instance.data.element = document.getElementById(“something” + properties.elementID)


And I’d use this anytime I want to call that html element in any plugin action/element


let box = instance.data.element

1 Like

Hi, if you had multiple button setup all calling the same function, how would you reference each button in the same function?

Can you give an example or do you have an example of code already implementing this?

Example - Code have numerous map style and there is a separate button to select the respective style. I was thinking one way was to use fields and create the necessary workflow. However, if events were something that could be used?

Sure. That makes sense.

That would make sense to me. Perhaps in your initialize or Update function you call a reference to the map like

‘’’

Var map = document.getElementById(“mapid”)
 Instance.data.map = map

‘’’

Then in your element action

‘’’

Var map = instance.data.map
map.customMapMethod()

‘’’

1 Like

how i can test the code, debug?

Run the code in a test app, right? There’s not really any other way to test it out most of the time since you’ll be reliant on a bubble input anyway for most plugins.

@jean_freitas

So, i cant identify the error. i wish run line by line and see the values

Not sure I understand. If you’re building a plugin and want to test the code, I’d add the plugin to an app as a tester and run with the console open and see what happens. Are you unable to do this?

I dont know how use the console to see the problem

I have problem to use the logic operator AND. i tried and, &, &&, +, etc. but i always receive this mensagem in console.