Element renders twice

I’m developing a plugin for Snipcart. An add to cart button. It works but Bubble renders the element twice. Here’s the simple code.

function(instance, properties, context) {
let el = $(“< i style=‘color:#fff;font-size:24px;cursor:pointer’ class=‘snipcart-add-item fa fa-cart-plus’>”);

el.attr({'data-item-id':properties.dataItemId,'data-item-name':properties.dataItemName,'data-item-price':properties.dataItemPrice,'data-item-description':properties.dataItemDescription,'data-item-image':properties.dataItemImage});
   
instance.canvas.append(el);
}

Any ideas?

It was an issue of the plugin testing mode. I reload the plugin editor page and now it works.

As the update function runs on page load and every time there is an upstream change to one of your properties it’s a good idea to accommodate that expected behaviour into your design.

Using initialize to host code that you want to only run once is the simplest way of doing that - typically that would include creating the host element and appending it to instance.canvas. Once your properties become available inside update you can update that host element, rather than replicate it.

Another measure that people take is to create place a ‘lock’ on certain parts of your plugin once it is setup… whatever ‘setup’ means with what you’re trying to do.

I do this by adding a key, initialised to instance.data during the initialize script - i.e. instance.data.initialized = false and toggling this to true within update once the data has loaded. You can then add some conditions to your update function in order to manage it - i.e. if (instance.data.initialized) { //do nothing } else { //load the data into the element }

2 Likes

Thanks for your advice. Sounds good.
I’ll give it a try.

this works, but seems a bit weird.

function(instance, properties, context) {
let el = $(instance.canvas[0].firstChild)
el.attr({‘data-item-id’:properties.dataItemId,‘data-item-name’:properties.dataItemName,‘data-item-price’:properties.dataItemPrice,‘data-item-description’:properties.dataItemDescription,‘data-item-image’:properties.dataItemImage});
}

This seems fine. Within initialize you could set instance.data.el to your appended DOM element. You can now just use instance.data.el to reference that JQuery object from update or any workflow action within the plugin - i.e. instance.data.el.attr({...}).

The basic pattern is to offload the work that’s non-recurring into initialized and run it only once, leaving update to be just that, a refresh for whenever data elsewhere has changed.

Cool. It works with instance.data.el.attr({})
Much cleaner as my version.

Thx.

1 Like