How can I use Airtable as a backend? - json

I am trying to use Airtable as backend for a submit form in my project. However, I cannot seem to integrate the API and I don’t know the problem. I am using React and axios.
I am very new to both JS and Airtable.
Below is my error code:
Error in the browser after submiting the form:
Airtable error: {“error”:{“type”:“INVALID_REQUEST_MISSING_FIELDS”,“message”:“Could not find field “fields” in the request body”}}
Could somebody please what I am doing wrong? Thanks a lot in advance!
Below is my code:
var form = document.querySelector("#bize-ulasin");
if(form) {
form.addEventListener("submit", function(event) {
event.preventDefault();
axios.post(airtable_write_endpoint,
{
"Content-Type": "application/json"
} ,
{
"fields": {
"AdSoyad": document.getElementById("#Ad-Soyad"),
"Email": document.getElementById("#Email"),
"Telefon": document.getElementById("#Telefon"),
"Konu": document.getElementById("#Konu"),
"Mesaj": document.getElementById("#Mesaj"),
"Ortam": "Websitesi"
}
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
})
})
};

This looks like an error with how you are structuring your axios call. It looks like you are actually passing {"Content-Type": "application/json"} as the payload in your POST call instead of the second parameter. You should be able to fix by re-ordering the parameters in your call:
axios.post(airtable_write_endpoint,
{
"fields": {
"AdSoyad": document.getElementById("#Ad-Soyad"),
"Email": document.getElementById("#Email"),
"Telefon": document.getElementById("#Telefon"),
"Konu": document.getElementById("#Konu"),
"Mesaj": document.getElementById("#Mesaj"),
"Ortam": "Websitesi"
},
}
{
headers: { "Content-Type": "application/json"}
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
})
})
Hope that helps!

Airtable has a JavaScript package which gives you programmatic access to any base within any of your Airtable worksheets. Airtable also generates the full API documentation for your bases. You can find your API when you go to: https://airtable.com/api
Select a base and you'll see a fully-fledged API with examples calls and all.
It shows the full JavaScript example:
EXAMPLE USING ENVIRONMENT VARIABLE
# Shell:
$ export AIRTABLE_API_KEY=YOUR_API_KEY
# Node:
const base = require('airtable').base('YOUR_AIRTABLE_BASE');
EXAMPLE USING CUSTOM CONFIGURATION
var Airtable = require('airtable');
Airtable.configure({
endpointUrl: 'https://api.airtable.com',
apiKey: 'YOUR_API_KEY'
});
var base = Airtable.base('YOUR_AIRTABLE_BASE');

"AdSoyad": document.getElementById("idname") select related html element,no value
you can solve with "AdSoyad": document.getElementById("Ad-Soyad").value and without id tag(#),you already wrote getElementById that doesn't need #

Related

wp-json API returns 401 on post edit with React and nonce

I am trying to create an admin page in WordPress with React that allows users to manage post content. I have successfully created a delete method in react to work with the API, but I'm having difficulties getting update to work.
// plugin_file.php
add_action('admin_enqueue_scripts', function() {
wp_localize_script('tfw-js', 'wpApiSettings', [
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' )
]);
});
The code above dumps this object near the bottom of my page
<script type='text/javascript'>
/* <![CDATA[ */
var wpApiSettings = {"root":"http:website.com\/wp-
json\/","nonce":"9eb4c99f2c"};
/* ]]> */
</script>
Here is the delete method that works as intended
deletePost(post) {
var _this = this;
this.serverRequest =
axios
.delete(wpApiSettings.root + "wp/v2/posts/" + post.id, {
headers: {'X-WP-Nonce': wpApiSettings.nonce},
})
.then(function(result) {
_this.updatePostList();
})
}
However my update method, that uses the same nonce key as delete returns 401 unauthorized. I am unsure if the using the same key is the correct approach, but admin-ajax.php uses the same nonce key so I am guessing it is.
updatePost(post) {
var _this = this;
this.serverRequest =
axios
.put(wpApiSettings.root + "wp/v2/posts/" + post.id, {
headers: {'X-WP-Nonce':wpApiSettings.nonce},
data : {
title: 'test'
}
})
.then(function(result) {
_this.updatePostList();
})
}
Error that is returned
{"code":"rest_cannot_edit","message":"Sorry, you are not allowed to edit this post.","data":{"status":401}}
I would prefer not to use an additional plugin to manage this.
Thanks!
Update:
I got this to work easily using jQuery. Not that big of a deal for me as I am just trying to learn React. Still curious if anyone can fill me in on why axios does not work with the exact same headers & post data. My current solution:
updatePost(post) {
var _this = this;
jQuery.ajax({
type: "POST",
url: wpApiSettings.root + "wp/v2/posts/" + post.id,
data: {
"title": 'test',
},
beforeSend: function( xhr ) {
xhr.setRequestHeader("X-WP-Nonce", wpApiSettings.nonce);
}
}).done(function(response) {
_this.updatePostList();
})
.fail(function() {
alert( "error" );
});
}
Hey so I have been having the same issues getting this work as well, but after a long day of troubleshooting, the fix to this was actually fairly simple and easy to overlook.
axios.put(wpApiSettings.root + "wp/v2/posts/" + post.id,
{ headers: {'X-WP-Nonce':wpApiSettings.nonce}},
{ title: 'test' })
should be
axios.put(wpApiSettings.root + "wp/v2/posts/" + post.id,
{ title: 'test' },
{ headers: {'X-WP-Nonce':wpApiSettings.nonce}})
I can't believe I misssed this, but the headers should be in an object that is always the third parameter of the PUT or POST functions in Axios. If you don't have any data you want to pass as the second parameter you could also use throw an empty string ''.
I didn't realize the parameter positions mattered, but in the Axios documentation, the prototype is axios.put(url[, data[, config]]). I got it figured out with a friend when we realized that we were putting the header object into the request body instead of actually putting it into the header.
Hope this helps!
You have to
axios.defaults.headers.common['X-WP-Nonce'] = wpApiSettings.nonce;
before sending a request. Best practice would be to set it at your constructor.
and always remember to use qs to serialize your object before sending it.

AJAX HTTP-POST-Request - Saving JSON responses

I want to make a HTTP-POST-Request with AJAX to call a JSON API. So, the API should return a response in JSON. I can see on the console of the API, that the request is successful. But the problem is, that no data or status is returned, or that I can't use it with JQuery. Here is my function:
$.post("http://api-adress/controller",
{
email: input_mail,
password: input_pw
},
function(data, status){
alert(data);
alert(status);
}, 'json');
I guess the problem is that the response from the Server does not get saved in the variables data and status correctly.
I would suggest to change a little bit your code like below:
var dataString = {
email: input_mail,
password: input_pw
}
$.post("http://api-adress/controller", dataString, function (result) {
})
.done(function (result) {
//Here is your result. You must parseJSON if it is json format
var data = jQuery.parseJSON(result);
})
.fail(function () {
//use this if you need it
})
Also make sure that you get the response through firebug in console tab. You can check there what you post, what you get etc.

Express: How to implement the JSON API

I have a very basic express server which simply offers model-data via mongoose for webapps. So now since in my Framework (ember) the JSON-API is the new default adapter for requesting model-data, Im wondering how to implement a response for my route in a way which respects the JSON API specification.
My current route in express looks like that.
router.get('/:id', function(req, res, next) {
postModel.find({ //Mongoose functions
_id: req.params.id
}, function(err, doc) {
res.json({ //returning the doc
data: doc //within 'doc', the 'type'-key must be added
});
});
});
I have to include a key for the "type" in each responded object so the responding object will looks like that:
{
data:{
type:"post",
id:"123",
title:"test"
}
}
Here is a better answer. My request handler in express:
router.get('/:id', function(req, res, next) {
Lookup.findById(req.params.id, function(err, result) {
if (err) {
res.send({
error: err
});
} else {
res.send(to_jsonapi(result, 'lookup'));
}
});
});
This calls a utility function which converts the mongoose result into a valid jsonapi result. You just need to call it with the result plus the 'type' value.
function to_jsonapi(result, type) {
datajson = [];
if (Array.isArray(result)) {
result.forEach(function(item) {
datajson.push({
"type": type,
"id": item._id,
"attributes": item
});
});
} else if (typeof result === "object") {
// Happens when there is only one item
datajson.push({
"type": type,
"id": result._id,
"attributes": result
});
} else {
datajson.push({
"type": type
});
}
return {
"data": datajson
};
}
This is not perfect yet but should get you down the road!
I am just running in to this same problem. There is an ember-mongoose npm package but I have not used it yet. The way they solve the problem is actually back in the ember-data side by extending the DS.RESTAdapter. There they overwrite the findQuery function.
findQuery: function(store, type, query) {
var data = { query: query };
return this.ajax(this.buildURL(type.typeKey), 'POST', { data: data });
}
This is not that elegant though since it requires a customization for every data type. You can see the example here.
Hope it helps.
Try using lean()
router.get('/:id', function(req, res, next) {
postModel
.find({_id: req.params.id})
.lean()
.then( docs => {
_.each( docs, doc => {
doc.type = "post";
});
res.json(data: docs);
});
});
If you are implementing jsonapi on server side because it will be then automatically parsed by your Ember.js Data, then I would suggest to look at different Serializers which Ember.js provides. It will solve the problem. Because it's the job of the client to parse the data in whatever way Backend provides, not that we have to make our backend compatible with clients :)

Capture and display laravel validation errors returned from an $http.post in angularjs

i am a newbie to laravel and laravel 5 and so ar i am having such a hard time, it's just problem after problem, my current issues is this, i am using angular js on my frontend, so i already have client side validation working and implemented, now when i send my form via $http.post the form is also validated on the server, if there are validation errors it returns the whole page in the response but what i want is only the errors returned as json, i am currently trying my hands on user registration not a custom one but the one that already comes with laravel 5.
this is my register.js:
(function() {
angular.module('vendor').controller('RegisterController', ['$http', '$scope', function($http, $scope) {
$scope.d = {};
$scope.register = function() {
$http.post(
'/auth/register',
{
_token: $scope.d._token,
email: $scope.d.email,
password: $scope.d.password,
password_confirmation: $scope.d.password_confirmation
},
{
'X-Requested-With': 'XMLHttpRequest'
}
).success(function(data) {
// get errors here
});
};
}]);
}) ();
You are going to want to capture and log the errors like so:
$http.post(
'/auth/register',
{
_token: $scope.d._token,
email: $scope.d.email,
password: $scope.d.password,
password_confirmation: $scope.d.password_confirmation
},
{
'X-Requested-With': 'XMLHttpRequest'
}
).success(function(data) {
// successs
}).error(function(error) {
// error
console.log(error);
});
https://docs.angularjs.org/api/ng/service/$http

AngularJS ngResource Send data to server with JSON and get response

In my angular JS app i need to send data to server:
"profile":"OLTP",
"security":"rsh",
"availability":"4",
"performance": {
"TRANSACTION_PER_SEC":1000,
"RESPONSE_TIME":200,
"CONCURRENT_CONNECTION_COUNT":500,
"STORAGE_SIZE":200,
"TOTAL_CONNECTION_COUNT":500
}
and in return i'll get
{"estimate" : 1600,"quoteid" : "Q1234"}
I was trying to do that with $resource but I am lost in syntax.
app.factory("VaaniEstimateService", function($resource) {
var requestURL = "http://128.34.32.34:8080/enquiry";
return $resource(requestURL, {callback: 'JSON_CALLBACK'}, { get: { method:'JSON'}, isArray:false });
});
Can you please provide me something to get me on the right path.
You must use JSONP method and insert JSON_CALLBACK keyword to your url as callback function.
app.factory("VaaniEstimateService", function($resource) {
return $resource("http://128.34.32.34:8080/enquiry?callback=JSON_CALLBACK", {}, {
get: {
method:'JSONP'
},
isArray:false
}).get({
profile:"OLTP",
security:"rsh",
availability:"4",
"performance.TRANSACTION_PER_SEC":1000,
"performance.RESPONSE_TIME":200,
"performance.CONCURRENT_CONNECTION_COUNT":500,
"performance.STORAGE_SIZE":200,
"performance.TOTAL_CONNECTION_COUNT":500
}, function (response) {
console.log('Success, data received!', response);
});
});
Your params will be sent as query params. Angularjs will automatically generate a global function for callback and replace its name with JSON_CALLBACK keyword. Your server must return json as javascript code by calling function that sent with callback parameter. For example, AngularJS is going to make GET request to that url:
http://128.34.32.34:8080/enquiry?callback=angular.callbacks._0?availability=4&performance.CONCURRENT_CONNECTION_COUNT=500&performance.RESPONSE_TIME=200&performance.STORAGE_SIZE=200&performance.TOTAL_CONNECTION_COUNT=500&performance.TRANSACTION_PER_SEC=1000&profile=OLTP&security=rsh
And your server must return response like that:
angular.callbacks._0({"estimate" : 1600,"quoteid" : "Q1234"});
Hope that's enough to give you an idea how jsonp works.