Google Apps Script webapp is converting submitted data values to array - json

I have a form on my website that submits its data to a Google App Script which then does some stuff and returns a status back to the web page. For some reason, when it reads in the submitted data, it is converting each value to an array containing just the value. For example:
{
fname: "danny",
lanme: "tester"
}
is being converted to
{
fname[]: ["danny"],
lanme[]: ["tester"]
}
** also not the [] being appended to the property name;
Here's a simple example:
HTML
<form>
<input type="text" name="fname"> <input type="text" name="lname">
<submit>
</form>
JavaScript
var payload = {
fname: $('[name="fname"]').val(),
lname: $('[name="lname"]').val()
}
$('form').submit(function() {
$.ajax({
url: 'https://script.google.com/macros/s/SCRIPT_ID/exec',
data: payload
method: 'GET"',
dataType: 'jsonp',
success: function(data) {
console.log(JSON.parse(data.body));
}
});
});
Google Apps Script
function doGet(e) {
var data = e.parameters;
return ContentService
.createTextOutput(JSON.stringify(data))
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
When run, the following is written to the console:
{fname: Array(1), lname: Array(1)}
and expanding it produces
fname: ["danny"]
lanme: ["tester"]
It's easy enough to convert in the Google Apps Script, but it would be nice to know why this is happening. Any ideas?

That is the way that the parameters property works.
You might change your doGet function by replacing
var data = e.parameters;
by
var data = {
fname:e.parameter.fname,
lname:e.parameter.lname
};
or by
var data = {};
Object.keys(e.parameter).forEach(key => data[key] = e.parameter[key]);
Resources
https://developers.google.com/apps-script/guides/web

Related

Google API Autocomplete in SvelteKit

I am building an application where I need to get the value return from the API and bind it to my variable. I have been stuck on this for days, and I couldn't go any further.
Here is my code:
<script>
let address = "";
async function addExample() {
const response = await fetch(
"https://api",
{
method: "PUT",
headers: {
"api-key":
"api-key",
},
body: JSON.stringify({
address: address,
}),
}
);
}
</script>
<svelte:head>
<script
src="https://maps.googleapis.com/maps/api/js?key=my-key&libraries=places&callback=initAutocomplete"
async
defer
>
</script>
<script>
let autocomplete;
function initAutocomplete() {
const input = document.getElementById("autocomplete");
const options = {
componentRestrictions: { country: "au" },
strictBounds: false,
};
const autocomplete = new google.maps.places.Autocomplete(
input,
options
);
}
autocomplete.addListener("place_changed", onPlaceChanged);
function onPlaceChanged() {
address = autocomplete.getPlace();
}
</script>
</svelte:head>
<input
id="autocomplete"
placeholder="address"
type="text"
bind:value={address}
/><br />
I tried to add my tag svelte:head inisde the script tag but it didn't work, among others tries. And due my lack of experience, I want if I'm doind this on the right way instead of waste more time on this. PS: I don't need to create a map or anything like that now. I just want to bind the value of autocomplete to my variable, so I will be able to fetch data into DB.
I have tried eveything I could find googling but none of them worked. I am newbie with all this, and I don't know what else to think/try.

Google Apps Script - URL Fetch App returning random numbers

I am new to Apps Script and was trying to build an API and call that API through a different script. I created the web app and published it.
This is the URL:
https://script.google.com/macros/s/AKfycbxKVmGy3fxDfoHxyDtQh7psqj7IdKF7qHbgxLAwNRoiKTA-bpKN4QKtArzwsYdFb-Hb/exec
When I open this link, I can see the data correctly but when I try to fetch this data from a different script using urlfetchapp, it returns random numbers. I need help on what I am doing incorrectly.
Script which I am using to call this data:
function GetCopies()
{
var options = {
'contentType': "application/json",
'method' : 'get',
};
var Data = UrlFetchApp.fetch('https://script.google.com/macros/s/AKfycbxKVmGy3fxDfoHxyDtQh7psqj7IdKF7qHbgxLAwNRoiKTA-bpKN4QKtArzwsYdFb-Hb/exec',options)
Logger.log(Data.getContent())
}
This is the log I get:
I tried parsing it, but it throws an error:
How can I get data from URL correctly?
A working sample:
Create two Google Apps Script projects. In my case API and fetcher
API
const doGet = () => {
const myObj = {
"name": "Mr.GAS",
"email": "mrgas#blabla.com"
}
return ContentService
.createTextOutput(JSON.stringify(myObj))
.setMimeType(
ContentService.MimeType.JSON
)
}
fetcher
const LINK = "API_LINK"
const fetchTheAPI = async () => {
const options = {
'contentType': "application/json",
'method': 'get',
}
const res = UrlFetchApp.fetch(LINK, options)
const text = res.getContentText()
console.log(JSON.parse(text))
}
Deploy the API: Select type > Web app and Who has access > Anyone, copy the URL (it is important to copy that URL not the one redirected in the browser)
Replace the "API_LINK" by the URL.
Run the function.
You only need to adapt this example to suit your needs.
Documentation:
Content Service
Web Apps

How to change an Apify actor parameter via API

I want to call an Apify actor and specify a parameter value via a call to the Apify API.
The actor is the Google Search Results Scraper located here.
Here is where the docs say to use queries as the object property name in the API call payload.
The following table shows specification of the actor INPUT fields as defined by its input schema. These fields can be [...] provided in a JSON object when running the actor using the API. Read more in docs.
...
Search queries or URLs
Google Search queries (e.g. food in NYC) and/or full URLs (e.g. https://www.google.com/search?q=food+NYC).
Enter one item per line.
Optional
Type: String
JSON example
"queries": "Hotels in NYC
Restaurants in NYC
https://www.google.com/search?q=restaurants+in+NYC"
After I run my Google Apps Script code, I expect to see a change in the searchQueries.term parameter to be the following.
Apify — what I expect to see
"searchQuery": {
"term": "Banks in Phoenix", // what I am trying to change to by API call
// [...]
},
But what I actually get is the same parameter value as existed the last time I ran the actor manually. As follows.
Apify — what I actually see
"searchQuery": {
"term": "CPA firms in Newark", // remaining from last time I ran the actor manually
// [...]
},
Here is the code I'm running from Google Apps Script.
Code.gs
const runSearch = () => {
const apiEndpoint= `https://api.apify.com/v2/actor-tasks/<MY-TASK-NAME>/run-sync?token=<MY-TOKEN>`
const formData = {
method: 'post',
queries: 'Banks in Phoenix',
};
const options = {
body: formData,
headers: {
'Content-Type': 'application/json',
},
};
UrlFetchApp.fetch(apiEndpoint, options,);
}
What am I doing wrong?
You are missing the payload property in the request object.
Change:
queries: 'Banks in Phoenix',
to:
payload: {
queries: 'Banks in Phoenix',
}
Code.gs
const runSearch = () => {
const apiEndpoint= `https://api.apify.com/v2/actor-tasks/<MY-TASK-NAME>/run-sync?token=<MY-TOKEN>`
const formData = {
method: 'post',
payload: {
queries: 'Banks in Phoenix',
},
};
const options = {
body: formData,
headers: {
'Content-Type': 'application/json',
},
};
UrlFetchApp.fetch(apiEndpoint, options,);
}

error handling for server errors with Google Apps Script

I'm building a WebApp that creates a Google Document from a template and contains some user supplied data as well as data fetched from a 3rd party service. Since all of the Class (DriveApp, DocumentApp, etc) methods make a request to the Google server, a server glitch could cause a simple statement like var doc = DocumentApp.openById(DOC_ID); to fail, throw an error and stop the entire process dead in its tracks... without the user having any idea why everything appears to be "frozen" (unless he is savvy enough to check the console).
For that reason, would it be appropriate to wrap any/all functions using those methods in a try/catch? Something like:
function createDoc(DOC_ID) {
try {
var doc = DocumentApp.openById(DOC_ID);
DriveApp.someMethod(...);
doc.someOtherDocumentMethod();
...
} catch(e) {
handleServerError(e);
return false;
}
return doc;
}
or is there a better way to handle any errors that may be out of the developer's control?
EDIT
Here's the request I send from my HTML page...
$('form').submit(function(e) {
e.preventDefault();
var obj = $('form').serializeObject();
var gurl = 'https://script.google.com/macros/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec';
$.ajax({
url: gurl,
type : "GET",
data: obj,
dataType: 'jsonp',
success : function (data, status, xhr) {
console.log("success");
console.log(data);
},
complete : function (xhr, status) {
console.log("complete");
}
});
});

how to get data from json in servlet

function getvalue1(){
debugger
var str=document.getElementById("SystemName").value;
var str1=document.getElementById("IP").value;
var str2=document.getElementById("SystemLevel").value;
var str3=document.getElementById("Ownera").value;
var str4=document.getElementById("Ownerb").value;
var str5=document.getElementById("SystemDesc").value;
var str6=document.getElementById("SystemDate").value;
var str7=document.getElementById("Recorder").value;
$.ajax({
type:"post",
url:"../AddServlet",
data: {
str:str,
str1:str1,
str2:str2,
str3:str3,
str4:str4,
str5:str5,
str6:str6,
str7:str7
},
async:false,
dataType:"json",
contentType:"application/json;charset=utf-8",
success:function (data) {
$.message.alert('successful');
},
error:function () {
alert("failedjump");
}
});
}
The previous is my js code, I wanna to take these "strs" into the servlet, I programmed servlet part to get the data is
enter image description here
But these strings are null in the servlet. How can I get the JSON data? thx!
getParameter will read standard form encoded data, not JSON data.
This wouldn't normally be a problem because you are sending standard form encoded data, not JSON.
However, since you have said contentType:"application/json;charset=utf-8", you are claiming to be sending JSON, so it isn't being parsed.
Remove that line.