Using await inside publishComposite fn

Hi!

I have an old publishComposite fn that downloads info from an API and then upserts it into a Collection.

I acknowledge that making API callouts in a publication is probably not recommended. The upsert code has been refactored to use bulkOperation and rawCollection. As a result, it’s using async/await.

My question is if it’s ok to use an async fn inside a publishComposite.

Meteor.publishComposite('records', function (recordNum) {
    //DL from network
    const record = Meteor.call("getRecordsFromAPI", recordNum);
    
    //IIFE to then upsert
    (async () => {
      const recordUpsert = await addRecordsFromApi(record, this.userId);
    })();
  }

Thanks!

Update: It looks like the async code does not get waited on. Code following it that returns a cursor gets called first.

Untested code, maybe try the following:

Meteor.publishComposite('records', async function (recordNum) {
    //DL from network
    const record = Meteor.call("getRecordsFromAPI", recordNum);
    const recordUpsert = await addRecordsFromApi(record, this.userId);

  }
1 Like

For the async part you may want to try this:

const recordUpsert = Promise.await(addRecordsFromApi(record, this.userId));

…or, even more surprisingly:

const recordUpsert = addRecordsFromApi(record, this.userId).await();

In the above cases no function needs to be made async.

For details see

3 Likes

This did not work. The publishcomposite library didn’t like async cb being passed in

These both worked perfectly! And thanks for the references! I still gotta wrap my head around Fibers.

Any insights on using the static method vs the chained version? I opted for the latter.

Thanks again!

You’re welcome! I don’t see any difference between the two versions with respect to their functionality, so I guess it’s more a question of personal preference.

The first one is a bit more verbose; however, it is likely to draw some attention to the fact that a Promise is in play.

The second one is less verbose, but it requires more attention from the reader of the code to realize what’s going on.

It is worth noting that these are purely Meteor specific extensions of Promise, and thus will work only in a Meteor app; therefore any code snippet that leverages these extensions can’t simply be reused in a, say, ordinary Node.js application.

Finally, and just to state the obvious, the great benefit of these Promise extensions is that they provide the equivalence of an await without having to declare the surrounding function async.

2 Likes

Very good points!

The Meteor syntactic sugar is great. Could’ve prevented me from having a bunch of async IIFEs everywhere haha

1 Like