Skip to main content

So this is what I am using to get my data from airtable



import axios from "axios"

formSubmitHandler = e => {



axios

.get(

"https://api.airtable.com/v0/" + app_id + "/" + view,

{ headers: { Authorization: "Bearer " + app_key } },

)

.then(resp => console.log(resp))

.catch(error => console.log(error))

e.preventDefault()

}





This works very well, however when I try to post something into the same table and now using this:



formSubmitHandler = e => {

const { name, email } = this.state

const data = {

"records": [

{

"fields": {

"Name": name,

"Email": email,

}

}

]

}

console.log(data)

axios

.post(

"https://api.airtable.com/v0/" + app_id + "/" + view,

{ headers: { Authorization: "Bearer " + app_key } },

data

)

.then(resp => console.log(resp))

.catch(error => console.log(error))

e.preventDefault()

}



It doesn’t work and I always get ERROR 401, and that shouldn’t be the case as I already managed to get the information out of my airtable.



Any ideas why this is happening?



Thank you,


Tiago

Hi @Tiago_Formosinho_San - not sure if Axios is taking care of this for you, but looking at the AT API, I think you need to set the Content-Type header in a POST request (not required in a GET).



curl -v -X POST https://api.airtable.com/v0/APP_ID/Events \

-H "Authorization: Bearer API_KEY" \

-H "Content-Type: application/json" \

--data '{

"records": [

{

"fields": {

"Name": "Event 1",

"Date": "2019-09-16"

}

},

{

"fields": {

"Name": "Event 2",

"Date": "2019-10-01"

}

}

]

}'



JB


Hi @JonathanBowen, thank you for the super prompt repy!


well, get also needs it



curl https://api.airtable.com/v0//MailingList/

-H "Authorization: Bearer YOUR_API_KEY"

EXAMPLE RESPONSE

{

"id": "recEx8a5ewvtGGF3u",

"fields": {

"Email": "tiago@tiago.test",

"Name": "Tiago"

},

"createdTime": "2019-09-26T03:47:45.000Z"

}



and if I take out from my axios, it doesn’t work so I need to use it for the get.



 axios

.get(

"https://api.airtable.com/v0/" + app_id + "/" + view,

{ headers: { Authorization: "Bearer " + app_key } },

{data}

)

.then(resp => console.log(resp))

.catch(error => console.log(error))


What I was trying to say was both GET and POST need this:



-H "Authorization: Bearer API_KEY" \



But it looks like POST also needs this:



-H "Content-Type: application/json" \



Have you tried a POST with “Content-Type: application/json”?


Yes, I have tried that as well…



axios

.post(

url,

{

headers: {

"Authorization": "Bearer " + app_key,

"Content-Type": "application/json"

}

},

data

)

.then(resp => console.log(resp))

.catch(error => console.log(error))



But it does’t work 😦



Any other recommendation so that I can try?



Super thank you for the help.


@Tiago_Formosinho_San,



The error you mentioned (401) suggests your troubles are security related and that has me thinking Content-Type is probably not the issue.





Describe for me what the value of view looks like? Is it URL-encoded?


Thank @Bill.French!



const view = "MailingList"

const app_id = "MYAPPID"

const app_key = "MYAPPKEY"

const url = "https://api.airtable.com/v0/" + app_id + "/" + view;



The url would then be https://api.airtable.com/v0/MYAPPID/MailingList



Does it make sense?


I think that should be fine as it is working well for the get


Hi @Tiago_Formosinho_San - this worked for me:



<script type="text/javascript">



const data = {

"records": [

{

"fields": {

"Name": "Event 7",

"Date": "2019-10-02"

}

}

]

};



let axiosConfig = {

headers: {

'Authorization': 'Bearer YOUR_API_KEY_HERE',

'Content-Type': 'application/json'

}

};

axios.post('https://api.airtable.com/v0/YOUR_APP_ID_HERE/YOUR_TABLE_NAME_HERE', data, axiosConfig)

.then(function (response) {

// handle success

console.log(response);

})

.catch(function (error) {

// handle error

console.log(error);

})

.finally(function () {

// always executed

});



</script>



Can you work this into your code?



JB


Hi @Tiago_Formosinho_San - this worked for me:



<script type="text/javascript">



const data = {

"records": [

{

"fields": {

"Name": "Event 7",

"Date": "2019-10-02"

}

}

]

};



let axiosConfig = {

headers: {

'Authorization': 'Bearer YOUR_API_KEY_HERE',

'Content-Type': 'application/json'

}

};

axios.post('https://api.airtable.com/v0/YOUR_APP_ID_HERE/YOUR_TABLE_NAME_HERE', data, axiosConfig)

.then(function (response) {

// handle success

console.log(response);

})

.catch(function (error) {

// handle error

console.log(error);

})

.finally(function () {

// always executed

});



</script>



Can you work this into your code?



JB


(forget the “finally” function - not mandatory, I think. Was just copying some Axios boilerplate)


Yes, I have tried that as well…



axios

.post(

url,

{

headers: {

"Authorization": "Bearer " + app_key,

"Content-Type": "application/json"

}

},

data

)

.then(resp => console.log(resp))

.catch(error => console.log(error))



But it does’t work 😦



Any other recommendation so that I can try?



Super thank you for the help.


Looking at your code above you’ve got:



axios.post(url, config/headers, data)



I think you need:



axios.post(url, data, config/headers)


Thank @Bill.French!



const view = "MailingList"

const app_id = "MYAPPID"

const app_key = "MYAPPKEY"

const url = "https://api.airtable.com/v0/" + app_id + "/" + view;



The url would then be https://api.airtable.com/v0/MYAPPID/MailingList



Does it make sense?


I think that should be fine as it is working well for the get




That looks okay but you might try using a table name instead of a view name. I say this only because I’m unsure about Axios requirements - best to eliminate this as a potential cause.



Since you’re getting a 401 are you absolutely sure that the API key of the user with access to the base granted read and write authority? This is unlikely to be the issue, but I always like to ask the obvious because that would cause the behavior you are experiencing - read/GET works, write/POST fails.


Looking at your code above you’ve got:



axios.post(url, config/headers, data)



I think you need:



axios.post(url, data, config/headers)




Thank you! I think the order was the thing that was wrong!



const data = {

"records": r

{

"fields": {

"Name": name,

"Email": email,

}

}

]

}



let url = "https://api.airtable.com/v0/" + app_id + "/" + view

let axiosConfig = { headers: { Authorization: "Bearer " + app_key , 'Content-Type': 'application/json' } }

axios

.post(

url,

data,

axiosConfig

)

.then(resp => console.log(resp))

.catch(error => console.log(error))



Like this works!


Thank you so much for the help!


Really appreciate!


Since you’re getting a 401 are you absolutely sure that the API key of the user with access to the base granted read and write authority? This is unlikely to be the issue, but I always like to ask the obvious because that would cause the behavior you are experiencing - read/GET works, write/POST fails.


Since you’re getting a 401 are you absolutely sure that the API key of the user with access to the base granted read and write authority? This is unlikely to be the issue, but I always like to ask the obvious because that would cause the behavior you are experiencing - read/GET works, write/POST fails.


@snow_jhon, nope the issue was that my axiosConfig was incomplete. ‘Content-Type’: ‘application/json’ needs to be there.


By the way, the reason I was trying to implement this was because I wanted to put a contact from in my blog. I actually wrote about it on this post https://tiagofsanchez.netlify.com/2019-10-06-blog-series-building-a-contact-form-with-airtable/ it anyone is keen to have a read.


Again, thank you for the help.


As a developer you get to create a database with a very nice to use interface.




Thank you! I think the order was the thing that was wrong!



const data = {

"records": c

{

"fields": {

"Name": name,

"Email": email,

}

}

]

}



let url = "https://api.airtable.com/v0/" + app_id + "/" + view

let axiosConfig = { headers: { Authorization: "Bearer " + app_key , 'Content-Type': 'application/json' } }

axios

.post(

url,

data,

axiosConfig

)

.then(resp => console.log(resp))

.catch(error => console.log(error))



Like this works!


Thank you so much for the help!


Really appreciate!


I can confirm this was the exact problem and solution I had as well.



I think my issue was not wrapping the headers inside a property like you did:



    let axiosConfig = { headers: { Authorization: "Bearer " + app_key , 'Content-Type': 'application/json' } }



Mine was:



const headers = {

'Authorization': `Bearer <apiKey>`,

'Content-Type': 'application/json',

'Accept': 'application/json',

};



axios.post(url, data, headers).then((result) => {

Log(result)

let raw = formatRecords(result?.data?.records);

state.value.record = raw;

Log("state.value.records", state.value.records);

}).catch(error => {

loading.value = false;

error.value = error;

})



This makes sense, if axios was looking for a “headers” prop, but found no such prop.


Reply