# Plugin Action (context.async) will not execute more than once

**URL:** <https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380>\
**Category:** Plugin builders\
**Created:** [May 25, 2022, 6:47pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380 "2022-05-25T18:47:57Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonah.deleseleuc](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/jonah.deleseleuc/32/199133_2.png) [@jonah.deleseleuc](https://forum.bubble.io/u/jonah.deleseleuc)\
**Post date:** [May 25, 2022, 6:47pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/1 "2022-05-25T18:47:57Z")

</div>

I have a plugin action …

 ![Capture](https://us1.discourse-cdn.com/bubble/original/3X/0/a/0ae45554a348532df944981207736854ad7bad53.png)

As you can see the function returns asynchronously and does a console log. Unfortunately the issue is that I perform this action one time and it works, but when I try to run it again it the code runs (the console.log(‘run’) is executed … ) but the **context.async** does not.

I’m not sure why that’s the case. What am I missing here? Any help would be appreciated 🙂

---

<div class="post-metadata">

**Author:** ![willihr10](https://avatars.discourse-cdn.com/v4/letter/w/43a26b/32.png) [@willihr10](https://forum.bubble.io/u/willihr10)\
**Post date:** [May 25, 2022, 7:46pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/2 "2022-05-25T19:46:07Z")

</div>

I have this exact same problem while using context.async in plugin element actions.  
I managed to run context.async several times on client-side actions only, with the exact same code.  
I believe this issue deserves a bug report.

---

<div class="post-metadata">

**Author:** ![jonah.deleseleuc](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/jonah.deleseleuc/32/199133_2.png) [@jonah.deleseleuc](https://forum.bubble.io/u/jonah.deleseleuc)\
**Post date:** [May 25, 2022, 8:07pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/3 "2022-05-25T20:07:26Z")

</div>

Really? Damn … So I need to use client-side actions I guess. ☹

---

<div class="post-metadata">

**Author:** ![aaronsheldon](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/aaronsheldon/32/115965_2.png) [@aaronsheldon](https://forum.bubble.io/u/aaronsheldon)\
**Post date:** [July 7, 2022, 9:42pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/4 "2022-07-07T21:42:45Z")

</div>

There are some mismatched design patterns in your use of promises and asynchronous functions:

1. Unless you need to extract a value from a promise or asynchronous function, or want to catch the promise rejection of a server side function in the server logs there is no need to wrap your asynchronous code in a`context.async`.
2. You are passing the (undefined) result of calling `console.log` to the error handling part of the callback. This is problematic and will result in unpredictable behaviour.
3. Ditto for your promise result, you are passing the (undefined) result of `console.log` to a eventually a return statement. Again more unpredictable behaviour.
4. Pick either `return Promise` or `async function` for your design pattern, not both. I personally prefer the older promise chaining as it forces me, as a developer, to think explicitly about asynchronous dependencies and orders of operation.

I would refactor your code to stick to one design pattern. For example using promise chaining:

```javascript
function(instance, properties, context) {

    // Start (writes first)
    console.log("Start");

    // Process (writes third)
    instance.data.whiteboard.board.get()
    .then((s) => { console.log(s); })
    .catch((r) => { console.log(r); });

     // End (writes second)
     console.log("End")
}

```

Note: there are browser and Node.js dependent idiosyncrasies when parsing anonymous functions. Some are more tolerant of partial syntax than others. I always use fully _“curly brace”_ anonymous syntax to guard against parser errors.

Server-side pattern using `context.async` to mimic `await` behaviour:

```javascript
const mypromise = makeapromise();
const myresolved = context.async(
    (callback) => {
        mypromise
        .then((result) => { callback(null, result); })
        .catch((reason) => { callback(reason); });
    }
);

```

Note: You can chain as many `then`s and `Promise.all`s or `Promise.any`s together outside of `context.async` before finally extracting a value with `context.async`

---

<div class="post-metadata">

**Author:** ![orth.dev.38](https://avatars.discourse-cdn.com/v4/letter/o/b4bc9f/32.png) [@orth.dev.38](https://forum.bubble.io/u/orth.dev.38)\
**Post date:** [January 23, 2023, 6:33am UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/5 "2023-01-23T06:33:23Z")

</div>

Still the same.  
Only one execution for plugin’s element action possible.  
So it seems impossible to async set elements states???

---

<div class="post-metadata">

**Author:** ![adam30](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/adam30/32/242266_2.png) [@adam30](https://forum.bubble.io/u/adam30)\
**Post date:** [April 14, 2023, 12:40pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/7 "2023-04-14T12:40:00Z")

</div>

I am having the same problem, has anyone found out how we can get around this?

---

<div class="post-metadata">

**Author:** ![jonah.deleseleuc](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/jonah.deleseleuc/32/199133_2.png) [@jonah.deleseleuc](https://forum.bubble.io/u/jonah.deleseleuc)\
**Post date:** [April 14, 2023, 12:51pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/8 "2023-04-14T12:51:42Z")

</div>

Only solution is to use a client side action by passing the instance via a global variable or via saving it to the html element.

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [April 14, 2023, 1:40pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/9 "2023-04-14T13:40:20Z")

</div>

Just for fun, you can try this in your element action:

```auto
if (instance.data.n === undefined) {
	instance.data.n = 0;
}
const myFN = async (cb) => {
	try {
		const value = await doAsyncStuff();
		instance.publishState("value", value);
		instance.triggerEvent("done");
		cb(null, value);
	} catch (e) {
		cb(e);
	}
};

myFN.toString = () => {
	return instance.data.n;
};

const value = context.async(myFN);

instance.data.n++;

```

and it will run the async function every thime you trigger the action.

**Of course it is an undocumented hack** ,  
it can probably break other internal functionality, it will probably not work once bubble changes the plugin async api.

**Do not use it in production**.

---

<div class="post-metadata">

**Author:** ![jonah.deleseleuc](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/jonah.deleseleuc/32/199133_2.png) [@jonah.deleseleuc](https://forum.bubble.io/u/jonah.deleseleuc)\
**Post date:** [April 14, 2023, 4:29pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/10 "2023-04-14T16:29:08Z")

</div>

You gotta live on the edge man… 🕶

use it in pro 😉

---

<div class="post-metadata">

**Author:** ![keith](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/keith/32/56020_2.png) [@keith](https://forum.bubble.io/u/keith)\
**Post date:** [April 15, 2023, 12:32am UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/11 "2023-04-15T00:32:24Z")

</div>

If you’re talking about element plugins, you can just use async/await syntax if you’re not loading any data. (If loading data, you’ll have to split your action into two parts, the first being the function that is called by the action code wherein you load your lists or things or whatnot and then calls an async function where you can await what needs to be awaited.)

---

<div class="post-metadata">

**Author:** ![Thimo](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/thimo/32/208917_2.png) [@Thimo](https://forum.bubble.io/u/Thimo)\
**Post date:** [February 1, 2024, 4:38pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/12 "2024-02-01T16:38:01Z")

</div>

Did anyone find a _real_ solution? The workaround from @dorilama works, but not sure if that would be the best way to fix this.

I reached out to Bubble support and they kinda admitted that `context.async` for Plugin Element Actions gets (wrongly) cached:

 ![2024-02-01 om 17.38.39](https://us1.discourse-cdn.com/bubble/original/3X/2/8/28c4c9f13340ca804530716ffd6044923790d7c0.png)

Bubble Support recommended to try out `context.v3.async` but that does **not** apply here as this is about Plugin **Element** Actions.

The next and final message from Bubble support stated that they do not offer support for 'custom code (_‘we’re unable to assist you further with custom code’_).

This is a very basic **reproducible example** : [Bubble | No-code apps](https://plugin-bug-demo.bubbleapps.io/version-test)

Would be amazing if anyone has made this work, or if we can confirm that @dorilama’s _workaround_ will not break in the future (CC: @grace.hong, @nick.carroll, @allenyang ) 🙂

---

<div class="post-metadata">

**Author:** ![dorilama](https://sea1.discourse-cdn.com/bubble/user_avatar/forum.bubble.io/dorilama/32/226878_2.png) [@dorilama](https://forum.bubble.io/u/dorilama)\
**Post date:** [February 1, 2024, 9:28pm UTC](https://forum.bubble.io/t/plugin-action-context-async-will-not-execute-more-than-once/208380/13 "2024-02-01T21:28:38Z")

</div>

nobody can confirm that that hack will not break in the future, that’s why you shouldn’t use it 🙃  
when I wrote that post it was working, but it was a funny excercise and I never used it in production.
