前提・実現したいこと
コードのgetInfo
関数で引数がコールバックになっているのですが、そこの部分でコールバックが存在しないというエラーが起こる
発生している問題・エラーメッセージ
/Users/user/dev/project/node_modules/google-spreadsheet/index.js:84 cb(); ^ TypeError: cb is not a function at /Users/user/dev/project/node_modules/google-spreadsheet/index.js:84:7 at /Users/user/dev/project/node_modules/google-spreadsheet/node_modules/google-auth-library/lib/auth/jwtclient.js:119:5 at /Users/user/dev/project/node_modules/google-spreadsheet/node_modules/google-auth-library/lib/auth/jwtclient.js:138:16 at Request._callback (/Users/user/dev/project/node_modules/google-spreadsheet/node_modules/gtoken/lib/index.js:228:14) at Request.self.callback (/Users/user/dev/project/node_modules/request/request.js:185:22) at Request.emit (events.js:197:13) at Request.<anonymous> (/Users/user/dev/project/node_modules/request/request.js:1161:10) at Request.emit (events.js:197:13) at IncomingMessage.<anonymous> (/Users/user/dev/project/node_modules/request/request.js:1083:12) at Object.onceWrapper (events.js:285:13)
js
1 /Users/user/dev/atom-tools/node_modules/google-spreadsheet/index.js 2 3 this.setAuthToken = function(auth_id) { 4 if (auth_mode == "anonymous") auth_mode = "token"; 5 setAuthAndDependencies(auth_id); 6 }; 7 8...中略 9 1075: function renewJwtAuth(cb) { 1176: auth_mode = "jwt"; 1277: jwt_client.authorize(function(err, token) { 1378: if (err) return cb(err); 1479: self.setAuthToken({ 1580: type: token.token_type, 1681: value: token.access_token, 1782: expires: token.expiry_date 1883: }); 1984: cb(); 2085: }); 2186: } 22 23・・・中略 24 25 function setAuthAndDependencies(auth) { 26 google_auth = auth; 27 if (!options.visibility) { 28 visibility = google_auth ? "private" : "public"; 29 } 30 if (!options.projection) { 31 projection = google_auth ? "full" : "values"; 32 } 33 } 34 35・・・中略 36 37 // public API methods 38 this.getInfo = function(cb) { 39 self.makeFeedRequest(["worksheets", ss_key], "GET", null, function( 40 err, 41 data 42 ) { 43 if (err) return cb(err); 44 if (data === true) { 45 return cb(new Error("No response to getInfo call")); 46 } 47 var ss_data = { 48 id: data.id, 49 title: data.title, 50 updated: data.updated, 51 author: data.author, 52 worksheets: [] 53 }; 54 var worksheets = forceArray(data.entry); 55 worksheets.forEach(function(ws_data) { 56 ss_data.worksheets.push(new SpreadsheetWorksheet(self, ws_data)); 57 }); 58 self.info = ss_data; 59 self.worksheets = ss_data.worksheets; 60 cb(null, ss_data); 61 }); 62 }; 63 64・・・中略 65 66 // This method is used internally to make all requests 67 this.makeFeedRequest = function(url_params, method, query_or_data, cb) { 68 var url; 69 var headers = {}; 70 if (!cb) cb = function() {}; 71 if (typeof url_params == "string") { 72 // used for edit / delete requests 73 url = url_params; 74 } else if (Array.isArray(url_params)) { 75 //used for get and post requets 76 url_params.push(visibility, projection); 77 url = GOOGLE_FEED_URL + url_params.join("/"); 78 } 79 80 async.series({ 81 auth: function(step) { 82 if (auth_mode != "jwt") return step(); 83 // check if jwt token is expired 84 if (google_auth && google_auth.expires > +new Date()) return step(); 85 renewJwtAuth(step); 86 }, 87 request: function(result, step) { 88 if (google_auth) { 89 if (google_auth.type === "Bearer") { 90 headers["Authorization"] = "Bearer " + google_auth.value; 91 } else { 92 headers["Authorization"] = "GoogleLogin auth=" + google_auth; 93 } 94 } 95 96 headers["Gdata-Version"] = "3.0"; 97 98 if (method == "POST" || method == "PUT") { 99 headers["content-type"] = "application/atom+xml"; 100 } 101 102 if ( 103 method == "PUT" || 104 (method == "POST" && url.indexOf("/batch") != -1) 105 ) { 106 headers["If-Match"] = "*"; 107 } 108 109 if (method == "GET" && query_or_data) { 110 var query = "?" + querystring.stringify(query_or_data); 111 // replacements are needed for using structured queries on getRows 112 query = query.replace(/%3E/g, ">"); 113 query = query.replace(/%3D/g, "="); 114 query = query.replace(/%3C/g, "<"); 115 url += query; 116 } 117 118 request( 119 { 120 url: url, 121 method: method, 122 headers: headers, 123 gzip: options.gzip !== undefined ? options.gzip : true, 124 body: method == "POST" || method == "PUT" ? query_or_data : null 125 }, 126 function(err, response, body) { 127 if (err) { 128 return cb(err); 129 } else if (response.statusCode === 401) { 130 return cb(new Error("Invalid authorization key.")); 131 } else if (response.statusCode >= 400) { 132 var message = _.isObject(body) 133 ? JSON.stringify(body) 134 : body.replace(/"/g, '"'); 135 return cb( 136 new Error( 137 "HTTP error " + 138 response.statusCode + 139 " (" + 140 http.STATUS_CODES[response.statusCode] 141 ) + 142 ") - " + 143 message 144 ); 145 } else if ( 146 response.statusCode === 200 && 147 response.headers["content-type"].indexOf("text/html") >= 0 148 ) { 149 return cb( 150 new Error( 151 "Sheet is private. Use authentication or make public. (see https://github.com/theoephraim/node-google-spreadsheet#a-note-on-authentication for details)" 152 ) 153 ); 154 } 155 156 if (body) { 157 var xml_parser = new xml2js.Parser({ 158 // options carried over from older version of xml2js 159 // might want to update how the code works, but for now this is fine 160 explicitArray: false, 161 explicitRoot: false 162 }); 163 xml_parser.parseString(body, function(err, result) { 164 if (err) { 165 xml_parser = null; 166 body = null; 167 return cb(err); 168 } 169 if (cb.length == 3) { 170 cb(null, result, body); 171 } else { 172 body = null; 173 cb(null, result); 174 } 175 }); 176 } else { 177 if (err) cb(err); 178 else cb(null, true); 179 } 180 } 181 ); 182 } 183 }); 184 };
該当のソースコード
js
1"use strict"; 2 3const googleSpreadSheet = require("google-spreadsheet"); 4 5const doc = new googleSpreadSheet( 6 "1X98eannyhE" 7); 8 9let sheet; 10 11const setAuth = () => 12 new Promise((resolve, reject) => { 13 const creds = require("./903c28f.json"); 14 doc.useServiceAccountAuth(creds, getInfoAndSheets()); 15 }); 16 17const getInfoAndSheets = () => 18 new Promise((resolve, reject) => { 19 doc.getInfo((err, info) => { 20 sheet = info.worksheets[0]; 21 }); 22 resolve(); 23 }); 24 25const workingWithCells = () => { 26 const COLUMS = { 27 name: 1, 28 price: 2 29 }; 30 sheet.getCells( 31 { 32 "min-row": 2, 33 "max-row": 5, 34 "return-empty": true 35 }, 36 (err, cells) => { 37 for (let i = 0; i < cells.length / sheet.colCount; i += 1) { 38 const name = cells[i * sheet.colCount + COLUMS.name].value; 39 const price = cells[i * sheet.colCount + COLUMS.price].value; 40 } 41 } 42 ); 43}; 44 45const a = async () => { 46 await setAuth(); 47 await workingWithCells(); 48}; 49 50const main = () => { 51 a(); 52}; 53 54main(); 55
試したこと
js
1const getInfoAndSheets = () => 2 new Promise((resolve, reject) => { 3 doc.getInfo((err, info) => { 4 sheet = info.worksheets[0]; 5 }); 6 resolve(); 7 });
上記の関数を下記に変更
const getInfoAndSheets = () => new Promise((resolve, reject) => { doc.getInfo((err, info) => { if(!info) info = function(){} sheet = info.worksheets[0]; }); resolve(); });
infoがないからエラーが起きているのかと思い、条件分岐を追加しましたが、あまり意味はなかったです。
補足
一応同じ症状の方が一人いたのですが、あまり解決策が出されていなかった
https://github.com/theoephraim/node-google-spreadsheet/issues/105
回答1件
あなたの回答
tips
プレビュー