How to Create New Google Spreadsheet Using googleapis in Node.js - javascript

I want to create a new Google Spreadsheet using googleapis package.
Thanks to Daniel Apt's answer, I am able to create the blank file of it. But I want to give the file values.
I tried this way
const createOption = {
resource: {
properties: {
title: 'Ini judul spreadsetnya'
},
values: ['a']
}
}
But it said that Invalid JSON payload received. Unknown name "values" at 'spreadsheet': Cannot find field.. What field should I add to insert the values? And how do I create the spreadsheet in specific folder? Thank you.

What you are trying to accomplish:
You want to create a new spreadsheet with specific values.
You want this spreadsheet to be created on a specific folder on Google Drive.
Solution:
The first step to accomplish this is to understand why you can't use the values property in your request.
Looking into the documentation you can see that the request is supposed to be of an instance Spreadsheet, and this type does not contain values.
You can also see that there is no way to specify where the spreadsheet will be created, since the Spreadsheet resource does not contain any reference to it's parent folder.
If we break it down, you actually want to do three things:
Create a new spreadsheet
Move it to a specific folder
Fill it with values
Note: You can do step 1 and 2 with a single API call
Create a new spreadsheet:
Change your request body to be like the following:
const createOption = {
resource: {
properties: {
title: 'Ini judul spreadsetnya'
}
}
};
Move the spreadsheet to another folder
You will need to use the Drive API to move a file.
You do this by updating the file to have another parent. In this case, you will use the file.update call with the addParents option where you can add a comma-separated list of parentIds.
These parentIds are the Ids of the folder your file should belong to. (Yes, you can have it in multiple places).
You can extract these via API or thru the interface:
Here is how your request should look like:
const driveMoveOption = {
fileId: "", //You will insert this later
addParents: "<YOUR PARENT ID HERE>",
removeParents: "root" //To remove it from the "MyDrive" section
}
And here is a sample of how to use it:
sheets.spreadsheets.create(createOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the `Spreadsheet` resource we want, with it's fileId
driveMoveOption.fileId = response.spreadsheetId; //Set the spreadsheet Id to
drive.files.update(driveMoveOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the structure of a Files structure: https://developers.google.com/drive/api/v3/reference/files#resource
});
});
Creating a spreadsheet on a specific folder
If you use the Drive.files.create API instead you can use this request:
{
"mimeType": "application/vnd.google-apps.spreadsheet",
"name": "Test",
"parents": [
"<YOUR PARENT ID HERE>"
]
}
and call it with
const driveCreateAndMoveOption = {
"mimeType": "application/vnd.google-apps.spreadsheet",
"name": "Test",
"parents": [
"<YOUR PARENT ID HERE>"
]
};
drive.files.update(driveCreateAndMoveOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the structure of a Files structure. Use this to get the file ID for the spreadsheet call.
});
Insert your custom values
The request to insert values on your spreadsheet should look something like this:
const appendOption = {
"spreadsheetId": "", //You will insert this later
"range": "A:A",
"valueInputOption": "USER_ENTERED",
"resource": {
"values": [
[
"a"
]
]
}
}
To use the correct SpreadsheetId you will need to run this code after you create it, and use that number.
This can be done like this:
sheets.spreadsheets.create(createOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the `Spreadsheet` resource we want, with it's fileId
appendOption.spreadsheetId = response.spreadsheetId; //Set the spreadsheet Id to insert the values on.
sheets.spreadsheets.values.append(appendOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the structure detailed on: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append#response-body
});
});

So as jonrsharpe's comment, finally I tried to create the blank spreadsheet and update it (there are two command call).

Related

GET request to webpage returns string, but cannot use it

I am creating a google chrome extension, and when I make a get request to this web page https://www.rightmove.co.uk/property-for-sale/find.html?locationIdentifier=REGION%5E27675&maxBedrooms=2&minBedrooms=2&sortType=6&propertyTypes=&mustHave=&dontShow=&furnishTypes=&keywords=, I get the webpage HTML as a response which is what I want (the website I am requesting info from does not have an API and I cannot web scrape for reasons too long to explain here). This response comes in the form of a string. When I attempt to split this string at a certain point, bis_skin_checked, I am returned an array of length 1, meaning that there was no match and nothing has been split. But when I look at the string returned it has it included.
I have tried things like removing spaces and carriage returns but nothing seems to be working. This is my GET request code:
function getNewPage(url) {
let returnedValue = fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'text/html',
},
})
.then(response => response.text())
.then(text => {
return text
})
return returnedValue
}
I then go on to resolve the promise which is returnedValue:
let newURL = getHousePrices(currentUrl) // Get Promise of new page as a string
newURL.then(function(value) { // Resolve promise and do stuff
console.log(value.split('bis_skin_checked').length)
})
And then work with the string which looks like this: (I have attached an image as I cannot copy the text from the popup)
Image Link To API Request return
I'm assuming you want to get the home values, given certain search parameters.
Scraping raw text is usually not the way to go. I took a look at the site and saw it uses uniform network requests that you can modify to capture the data you need directly instead of scraping the raw HTML.
I built a solution that allows you to dynamically pass whatever parameters you want to the getHomes() function. Passing nothing will use the default params that you can use as a baseline while you try to adjust the request for any additional modifications/use cases.
Install the below solution and run getHomes() from the service worker.
Here's a brief video I made explaining the solution: https://vimeo.com/772275354/07fd1025ed
--- manifest.JSON ---
{
"name": "UK Housing - Stackoverflow",
"description": "Example for how to make network requests and mimic them in background.js to avoid web scraping raw text",
"version": "1.0.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"host_permissions": [
"*://*.rightmove.co.uk/*"
]
}
--- background.js ---
async function getHomes(passedParams) {
const newParams = passedParams ? passedParams : {}; // set to an empty object if no new params passed - avoid error in object.entries loop.
// starts with default params for a working request, you can then pass params to override the defaults to test new requests.
var params = {
"locationIdentifier": "REGION%5E27675",
"maxBedrooms": "2",
"minBedrooms": "1",
"numberOfPropertiesPerPage": "25",
"radius": "0.0",
"sortType": "6",
"index": "0",
"viewType": "LIST",
"channel": "BUY",
"areaSizeUnit": "sqft",
"currencyCode": "GBP",
"isFetching": "false"
}
Object.entries(params).forEach(([key, value]) => {
// we iterate through each key in our default params to check if we passed a new value for that key.
// we then set the params object to the new value if we did.
if (newParams[key]) params[key] = newParams[key];
});
const rightMoveAPISearch = `https://www.rightmove.co.uk/api/_search?
locationIdentifier=${params['locationIdentifier']}
&maxBedrooms=${params['maxBedrooms']}
&minBedrooms=${params['minBedrooms']}
&numberOfPropertiesPerPage=${params['numberOfPropertiesPerPage']}
&radius=${params['radius']}
&sortType=${params['sortType']}
&index=${params['index']}
&viewType=${params['viewType']}
&channel=${params['channel']}
&areaSizeUnit=${params['areaSizeUnit']}
&currencyCode=${params['currencyCode']}
&isFetching=${params['isFetching']}
`.replace(/\s/g, ''); // removes the whitespaces we added to make it look nicer / easier to adjust.
const data = await
fetch(rightMoveAPISearch, {
"method": "GET",
})
.then(data => data.json())
.then(res => { return res })
if (data.resultCount) {
console.log('\x1b[32m%s\x1b[0m', 'Request successful! Result count: ', parseInt(data.resultCount));
console.log('All data: ', data);
console.log('Properties: ', data.properties);
}
else console.log('\x1b[31m%s\x1b[0m', `Issue with the request:`, data)
return data
}
Hope this is helpful. Let me know if you need anything else.

Firestore document update using REST api

I'm trying to increment one value in firebase store using rest api following this guide https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/commit
I'm trying to make the request using the form given at this documentation.
Here's my path to the document
/hindiscript-likes/kof97lbQ1IuuvgCHBfOh
where hindiscript-likes is the collection name.
The document looks like below
Here's my request body
{
"writes": [
{
"transform": {
"document": "projects/public-api-07/databases/(default)/documents/kof97lbQ1IuuvgCHBfOh",
"fieldTransforms": [
{
"increment": {
"integerValue": 1
}
}
]
}
}
]
}
But upon executing this, it is returnng 400 with the following error
{
"error": {
"code": 400,
"message": "Document name \"projects/public-api-07/databases/(default)/documents/kof97lbQ1IuuvgCHBfOh\" lacks \"/\" at index 73.",
"status": "INVALID_ARGUMENT"
}
}
Can somebody help ?
You're missing the name of the collection in the path of the document to update. What you have now is asking for just "kof97lbQ1IuuvgCHBfOh", which it assumes is the name of a collection but a missing document ID. But what you want instead is "hindiscript-likes/kof97lbQ1IuuvgCHBfOh".
Try:
"document": "projects/public-api-07/databases/(default)/documents/hindiscript-likes/kof97lbQ1IuuvgCHBfOh",

How to update a certain field in object using the Nodejs Request Patch while keeping the others as before

I have a API which returns the JSON data something like this:
{
"data":{
"id": "859545",
"name":"Batman",
"custom-fields": {
"--f-09":"custom-1",
"--f-10":"custom-2",
"--f-11":"custom-3"
},
"tags": [],
"created-at": "2021-09-10T15:45:16Z",
"updated-at": "2022-04-23T11:52:49Z"
}
}
For this JSON I would like to change the field "--f-09" to "custom-1, custom-new" and "--f-10" to "custom-2, custom-new" while keeping all other fields as before.
I am aware that I can use request.PATCH in Nodejs for this but in that case, I need to provide all the data again for the request which I would like to avoid. I just want to update certain fields while keeping others as before.
In this example, I have provided a simple example which contains only certain fields but in my real code I have many fields so does this mean that I need to build the response body json using all the fields again and just change the --f-09 and --f-10?
Following is the code:
const jsonBody = {
"data": {
"id": "859545",
"name": "Batman",
"custom-fields": {
"--f-09": "custom-1, custom-new",
"--f-10": "custom-2, custom-new",
"--f-11": "custom-2"
},
"tags": [],
"created-at": "2021-09-10T15:45:16Z",
"updated-at": "2022-04-23T11:52:49Z"
}
}
request.patch('https://reqres.in/api/users',jsonBody,function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
console.log(response.statusCode);
}
}
);
Does this mean that I need to build the complete JSON body again here just like I have built the jsonBody above while using the PATCH or is there any other way where I can just pass the value for --f-09 and --f-10?
First you check, what parameters do you want update is side the object. then you can filter , that values only. then you can merge separate parts in the object.

How i can get query string from file to query database in expressjs?

I'm trying to use this code but it's not working
var content = fs.readFileSync('/home/diegonode/Desktop/ExpressCart-master/views/partials2/menu8xz.hbs', 'utf8' );
req.db.products.find( content ).skip(0).limit(3).exec(function (err, results) {
please anyone help me (this is a extract of code)
i put the rest of code
req.db.products.find( content ).skip(0).limit(3).exec(function (err, results) {
res.render('index', {
title: 'Shop',
results: results,
session: req.session,
message: clear_session_value(req.session, "message"),
message_type: clear_session_value(req.session, "message_type" , req.body.product_id),
config: req.config.get('application'),
helpers: req.handlebars.helpers,
page_url: req.config.get('application').base_url,
show_footer: "show_footer"
});
console.log(content );
});
console.log(content );
});
It looks like your mapper's find function expects a conditions object, and when you read content directly from the file it's a plain text string that just happens to look like an object instead.
You need to do two things: first, "quote" product_title to make the file valid JSON; and second, use JSON.parse to turn content into an object which db.products.find can work with.

How do I change the .save() JSON output for ExtJS 4.2

I have a problem save data to my database using an ExtJS updateable grid.
I'm working with a REST API that I have written in Progress ABL.
The API is working but the Input JSON and Output JSON is very specific.
I can read the JSON data into my grid and display it, but when I want to save a new record the grid creates a wrong JSON output.
My output has to be like this:
{
"request":
{
"dsUsers":
{
"ttUsers":
[{"ID":20,"LOGIN":"test","PASS":"","ID_ADDR":0,"ID_CUST":0}]
}
}
}
But I'm not able to create the request and dsUsers groups in the writer.
I have tested a lot but I don't really know what I have to change to make it work.
Thanks
Base Ext.data.writer.Json allows you to define only root data property. However if you need more custom structure like this, you can quite easily create your own writer.
Your writer should extend from Ext.data.writer.Json and override writeRecords method. This method add records data into request.
In your case custom writer should look like this:
Ext.define('myWriter', {
extend: 'Ext.data.writer.Json',
writeRecords: function(request, data) {
var root = this.root;
if (this.expandData) {
data = this.getExpandedData(data);
}
if (this.allowSingle && data.length === 1) {
// convert to single object format
data = data[0];
}
request.jsonData = request.jsonData || {};
request.jsonData['request'] = {
'dsUsers': {}
};
request.jsonData['request']['dsUsers'][root] = data;
return request;
}
});
Then you can use your custom writer in model or store proxy:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email'],
proxy: {
type: 'rest',
writer: Ext.create('myWriter', {
root: 'ttUsers',
mainRoot: 'dsUsers'
}),
url : '/users'
}
});
Of course you can create custom writer more configurable and reusable by defining name of "request" and "dsUsers" attributes in config.
Fiddle with example: https://fiddle.sencha.com/#fiddle/33l

Categories

Resources