"submission-created.js" runs but skips call to Airtable...?

I’ve had a good hunt around code samples and these forms but can’t work this out.

I have a function that runs whenever a form is submitted (submission-created.js). I can see it runs in the Netlify logs:

4:35:13 PM: a4a2147f INFO   {
  number: 23,
  email: 'chris+333@getvero.com',
  body: null,
  data: {
    email: 'chris+333@getvero.com',
  },
  created_at: '2021-08-11T06:35:12.468Z',
  human_fields: { Email: 'chris+333@getvero.com' },
  id: '61136fa0b786a3b30c95bcae',
  form_id: '611354a060f6cc00079e5225',
  site_url: 'http://unruffled-wiles-fc4bfc.netlify.app',
  form_name: 'newsletter-subscribe'
}
4:35:13 PM: a4a2147f INFO   newsletter-subscribe
4:35:13 PM: a4a2147f INFO   /.netlify/functions/submission-created
4:35:13 PM: a4a2147f INFO   chris+333@getvero.com
4:35:13 PM: a4a2147f INFO   Configured
4:35:13 PM: a4a2147f INFO   Saved

You can see my console.log(XYZ) outputs in there.

However, despite running and saying Saved, it is not actually saving to Airtable. It’s entirely skipping these lines: newsletter-subscribers-demo/submission-created.js at master · getvero/newsletter-subscribers-demo · GitHub

…yet it’s doing so without an error.

I’m sure I’m doing something extremely basically wrong, but as this works locally with netlify dev, I’m at a loss.

Would welcome any help or advice on how I might capture further logs or even fix this!

Thanks :slight_smile:

You have console.log("Saved") outside base(AT_SUBSCRIPTION_TABLE).create() so it will log that to the console regardless (as I read it.)

Perhaps try logging out base as see that you get.

You also have console.log("Configured"); however you have no check to see that it actually is configured. Does airtable.configure({apiKey: AT_API_KEY}); not return something to tell you operation succeeded or failed (same thinking with base)?

Hi @chexton,

Well, for some reason, I can’t see airtable docs without singing up with them. I believe I need to refer to Airtable Web API?

But to summarise what could be the cause, let me explain in short how Lambda functions execute. It’s similar to normal JavaScript. The code is executed in the order it’s written. However, when doing this client-side, you have a longer wait time and more resources. But in serverless functions, the program just exits after the final return statement is hit. Thus, you need to make heavy use of async/await.

So, why I needed airtable docs is to see that how exactly the code should look? Not sure if the code you have can simply work by adding await keyword before your base(...) statement. But in short, you need to wait for the previous code to finish executing before you move on to the next.

This forum is amazing. Thanks @hrishikesh and @coelmay!

Taking on board both suggestions, I made some code changes: newsletter-subscribers-demo/submission-created.js at master · getvero/newsletter-subscribers-demo · GitHub

Here’s the output in my function log now (below). It looks like await didn’t work — but this is useful knowledge @hrishikesh and I will think on it. It sounds like I need to find a way to wait for the call out to Airtable to fully complete before proceeding. Perhaps using Promises (with which I’m not familiar yet!) is the way to go.

6:45:51 PM: 5f954193 INFO   Configured
6:45:51 PM: 5f954193 INFO   [Function: baseFn] {
  _base: Base { _airtable: Airtable {}, _id: 'appo9GIZlwPWaoOmt' },
  table: [Function: bound ],
  makeRequest: [Function: bound ],
  runAction: [Function: bound ],
  getId: [Function: bound ]
}
6:45:51 PM: 5f954193 INFO   undefined

Unfortunately, no luck yet.

Hi @chexton,

Could you confirm if I was trying to access the correct docs? If so, I can give this a shot from my end too.

I believe so @hrishikesh, though there is also https://www.airtable.com/developers/

The GitHub repo shows a different method for invocation than you are using.

You might have luck looking on the Airtable Community Forum too.

Hi @chexton,

I signed up with Airtable and got a basic demo working:

const Airtable = require('airtable')

exports.handler = async event => {

  const base = new Airtable({
    apiKey: 'api key'
  }).base('base key')

  return new Promise((resolve, reject) => {
    base('Table 1').create([{
      'fields': {
        'Email': event.queryStringParameters.email
      }
    }], error => {
      if (error) {
        reject(error)
      } else {
        resolve('Done')
      }
    })
  }).then(() => {
    return {
      statusCode: 200,
      body: JSON.stringify(true)
    }
  })

}

You can call it like: /.netlify/functions/functionName/?email=foo@bar.com.

This was my first time using Airbase so I’m not particularly sure what I’m doing, but I think I’ve got the basics figured out and tried to make it work. Hopefully, this will give you an idea.

2 Likes

Amazing @hrishikesh — thanks for going to all this trouble.

Your advice on how Lambda works + example + me going and reading up on Promises (which I’ve not used before) resulted in the final code:https://github.com/getvero/newsletter-subscribers-demo/blob/master/functions/submission-created.js

This line in particular helped me:

…in serverless functions, the program just exits after the final return statement is hit. Thus, you need to make heavy use of async/await.

This is working end-to-end now. I’m writing up a blog post with my learnings that can hopefully help others in future! Will post a link when I get that done.

We can safely say this is resolved.