theoephraim / node-google-spreadsheet

Google Sheets API wrapper for Javascript / Typescript
https://theoephraim.github.io/node-google-spreadsheet
The Unlicense
2.3k stars 388 forks source link

row.save erroring out - [Error: options.uri is a required argument] #136

Closed nihalansari closed 4 years ago

nihalansari commented 8 years ago

row.save is erroring out with the following error: [Error: options.uri is a required argument]

The code is:

row.save(function (err) {

                         if (err != null) {
                             console.log(err);
                         }
                    }
                    );
theoephraim commented 8 years ago

more context? how was row created? I think there is a known bug with creating new rows and then saving them.

Going to put some time in soon to fix some of the outstanding PRs

nihalansari commented 8 years ago

pasting the code below(cloned from another github code)


  function workingWithRows(step) {

        var tonecreds = require('./tone-credentials.json');

        var toneAnalyzer = watson.tone_analyzer(tonecreds);

        sheet.getRows({
            offset: 1,
            limit: 23
        }, function (err, rows) {
            rows.forEach(function (row) {
                // Concepts
                var parameters = {
                    //text: row.answer,
                    text: row.sometext,
                    knowledgeGraph: 1
                };

                var concepts = '';

                alchemy_language.concepts(parameters, function (err, response) {

                    if (err) {
                        console.log('error:', err);
                    } else {

                        response.concepts.forEach(function (concept) {
                            concepts = concepts + concept.text + ' - ';
                        });

                        row.concepts = concepts;
                        console.log("concepts: " + concepts);
                    }

                });

                toneAnalyzer.tone({
                    text: row.sometext,
                    sentences: false
                }, function (err, data) {
                    if (err) {
                        console.log(err);
                    }

                    var tones = data.document_tone.tone_categories[EMOTION].tones;

                    tones.forEach(function (tone) {

                        var score = Math.round(tone.score * 100);

                        switch (tone.tone_name) {

                        case 'Anger':
                            row.anger = score;
                            break;

                        case 'Disgust':
                            row.disgust = score;
                            break;

                        case 'Joy':
                            row.joy = score;
                            break;

                        case 'Sadness':
                            row.sadness = score;
                            break;

                        case 'Fear':
                            row.fear = score;
                            break;
                        }

                        console.log(tone.tone_name + ': ' + Math.round(tone.score * 100) + '%');
                    });

                     row.save(function (err) {

                        if (err != null) {
                             console.log(err);
                         }
                    }
                    );

                });
            })
        });
                }])
gregorskii commented 7 years ago

I think this may be due to a change in the Sheets API. On this line https://github.com/theoephraim/node-google-spreadsheet/blob/master/index.js#L501 self._links.edit is not there.

What do you think?

kvaillant commented 7 years ago

@gregorskii self._links.editis filled in from xml entry for row (precisely link entity) I debugged my app, logging every xml entry from google sheetrows, and I found out that there is no link property with attribute ref='edit' from today's google apis for spreadsheet. I have only :

<link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/xxxxx/od3/private/full/zzz'/>

Then while I was wondering why I didn't get any edit link, I opened my spreadsheet page and unthankfully discovered my sheet policy was only visible by people and not editable (probably google updates).

I set back to modify by whoever has link then everything got back to normal ! :)

gregorskii commented 7 years ago

Oh great! Will try on my end. Thanks!

gregorskii commented 7 years ago

Yep this worked for me. However any column in the row that is protected results in the row save returning a 400 with an error:

Error: HTTP error 400 (Bad Request) - You are trying to edit a protected cell or object. Please contact the spreadsheet owner to remove protection if you need to edit.
theoephraim commented 7 years ago

Hey guys, just catching up here.

So it seems that the issue is that permissions were not set correctly on the doc to be editable? And another related issue if the rows are "protected".

So not an actual bug, but could probably have some better error messaging? Is that right?

gregorskii commented 7 years ago

Yes in my case that was it. Wrong permissions, therefore the edit URL is not found. Better error messaging could alleviate that.

However having a single column being protected appears to throw an error stating I am editing a protected range. Is this API writing the entire object back without checking what has changed? If it tries to right each column back without checking if the value has changed it would produce the error found. However if it tracked changes to the internal object it uses to map to the row, and only wrote the changed values, it would work fine.

Thanks!

theoephraim commented 7 years ago

Yes it does include the entire row in the update. As far as I understood, this is how the "row based" API works for their API. I think it is designed this way to make sure there are not race conditions with concurrent updates. If some data is not correct, it throws an error.

To update the contents of an existing row, first retrieve the row to update, modify it as desired, and then send a PUT request, with the updated row in the message body, to the row's edit URL.

I also don't see anything in their docs about protected cells/ranges.

Things could have changed in v4 of the API which I haven't looked at just yet.

gregorskii commented 7 years ago

Ah ok. Removing protected rows is easy enough for my use. But looking forward to v4 when its ready.

Thanks!

theoephraim commented 4 years ago

I've just a published a new version of this module which is a complete rewrite using Google's V4 Sheets API (v3 is being deprecated on March 3, 2020). YOU MUST MIGRATE IF YOU ARE STILL USING THIS PACKAGE!

Docs available here - https://theoephraim.github.io/node-google-spreadsheet

Please test it out and if you find that there is still a problem, reopen the issue.

Thanks! 😄