检查 JSON 属性 是否存在
Checking if a JSON property exists
我正在从 Yahoo Finance 导入股票 JSON 数据,以使用自定义函数导入 Google 个人股票追踪器表格:
function _yahoofinance(ticker) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(ticker)
+ '?modules=price,assetProfile,summaryDetail,incomeStatementHistory,'
+ 'balanceSheetHistory,defaultKeyStatistics,financialData,calendarEvents,'
+ 'recommendationTrend,upgradeDowngradeHistory,majorHoldersBreakdown'
;
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const responseCode = response.getResponseCode();
if (responseCode === 200) {
const quote = JSON.parse(response.getContentText());
const price = _isEmpty(quote.quoteSummary.result[0].price.regularMarketPrice) ? '-' : quote.quoteSummary.result[0].price.regularMarketPrice.fmt;
const divYield = _isEmpty(quote.quoteSummary.result[0].summaryDetail.dividendYield) ? '-' : quote.quoteSummary.result[0].summaryDetail.dividendYield.raw * 100;
const payoutRatio = _isEmpty(quote.quoteSummary.result[0].summaryDetail.payoutRatio) ? '-' : quote.quoteSummary.result[0].summaryDetail.payoutRatio.raw * 100;
const marketCap = _isEmpty(quote.quoteSummary.result[0].summaryDetail.marketCap) ? '-' : quote.quoteSummary.result[0].summaryDetail.marketCap.fmt;
const fwdPE = _isEmpty(quote.quoteSummary.result[0].summaryDetail.forwardPE) ? '-' : quote.quoteSummary.result[0].summaryDetail.forwardPE.fmt;
const revenue = _isEmpty(quote.quoteSummary.result[0].financialData.totalRevenue) ? '-' : quote.quoteSummary.result[0].financialData.totalRevenue.fmt;
const revGrowth = _isEmpty(quote.quoteSummary.result[0].financialData.revenueGrowth) ? '-' : quote.quoteSummary.result[0].financialData.revenueGrowth.raw * 100;
const earnGrowth = _isEmpty(quote.quoteSummary.result[0].financialData.earningsGrowth) ? '-' : quote.quoteSummary.result[0].financialData.earningsGrowth.raw * 100;
const freeCash = _isEmpty(quote.quoteSummary.result[0].financialData.freeCashflow) ? '-' : quote.quoteSummary.result[0].financialData.freeCashflow.fmt;
return [[divYield, payoutRatio, marketCap, fwdPE, revenue, revGrowth, earnGrowth, freeCash]];
}
}
function _isEmpty(obj) {
return Object.keys(obj).length === undefined;
}
请查看示例 sheet here(选项卡 JSON
)。
问题是:并非每个代码都有我从雅虎请求的每个 属性。我尝试了很多不同的方法来处理这个问题:
const payoutRatio = _isEmpty(quote.quoteSummary.result[0].summaryDetail.payoutRatio)
function _isEmpty(obj) {
return Object.keys(obj).length === undefined;
}
但是 none 这行得通。在示例 sheet 中,我试图提取股票代码 0P0001703K.SW
的数据,这是一种 ETF,因此它不会具有股票所具有的所有属性。 Google 张 return 错误:
#Error! TypeError: Cannot read property 'totalRevenue' of undefined (line 19).
它快把我逼疯了 :D 我一直在尝试以多种方式捕捉此类错误。我的问题是:检查 属性 是否存在的正确方法是什么,如果不存在,只需 return -
并继续下一个 属性?非常感谢您的帮助!
[编辑] 解决方案:
function _yahoofinance(ticker) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(ticker)
+ '?modules=price,assetProfile,summaryDetail,incomeStatementHistory,'
+ 'balanceSheetHistory,defaultKeyStatistics,financialData,calendarEvents,'
+ 'recommendationTrend,upgradeDowngradeHistory,majorHoldersBreakdown'
;
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const responseCode = response.getResponseCode();
if (responseCode === 200) {
const quote = JSON.parse(response.getContentText());
const price = quote.quoteSummary.result[0]?.price?.regularMarketPrice?.fmt || '-';
const divYield = quote.quoteSummary.result[0]?.summaryDetail?.dividendYield?.raw ? '-' : quote.quoteSummary.result[0].summaryDetail.dividendYield.raw * 100;
const payoutRatio = quote.quoteSummary.result[0]?.summaryDetail?.payoutRatio?.raw ? '-' : quote.quoteSummary.result[0].summaryDetail.payoutRatio.raw * 100;
const revenue = quote.quoteSummary.result[0]?.financialData?.totalRevenue?.fmt || '-';
return [[price, divYield, payoutRatio, revenue]];
}
}
您可以使用 optional chaining 而不是 _isEmpty()
函数,因为您检查 quote.quoteSummary.result[0].financialData.totalRevenue
是否为空但错误显示 'totalRevenue' of undefined。这意味着 financialData
是未定义的,它甚至在进入您的 isEmpty 函数之前就会抛出错误。
在您的示例中,它类似于:
const quote = {
quoteSummary: {
result: [{}]
}
}
const revenue = quote.quoteSummary.result?.[0]?.financialData?.totalRevenue?.fmt || '-';
console.log(revenue);
我正在从 Yahoo Finance 导入股票 JSON 数据,以使用自定义函数导入 Google 个人股票追踪器表格:
function _yahoofinance(ticker) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(ticker)
+ '?modules=price,assetProfile,summaryDetail,incomeStatementHistory,'
+ 'balanceSheetHistory,defaultKeyStatistics,financialData,calendarEvents,'
+ 'recommendationTrend,upgradeDowngradeHistory,majorHoldersBreakdown'
;
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const responseCode = response.getResponseCode();
if (responseCode === 200) {
const quote = JSON.parse(response.getContentText());
const price = _isEmpty(quote.quoteSummary.result[0].price.regularMarketPrice) ? '-' : quote.quoteSummary.result[0].price.regularMarketPrice.fmt;
const divYield = _isEmpty(quote.quoteSummary.result[0].summaryDetail.dividendYield) ? '-' : quote.quoteSummary.result[0].summaryDetail.dividendYield.raw * 100;
const payoutRatio = _isEmpty(quote.quoteSummary.result[0].summaryDetail.payoutRatio) ? '-' : quote.quoteSummary.result[0].summaryDetail.payoutRatio.raw * 100;
const marketCap = _isEmpty(quote.quoteSummary.result[0].summaryDetail.marketCap) ? '-' : quote.quoteSummary.result[0].summaryDetail.marketCap.fmt;
const fwdPE = _isEmpty(quote.quoteSummary.result[0].summaryDetail.forwardPE) ? '-' : quote.quoteSummary.result[0].summaryDetail.forwardPE.fmt;
const revenue = _isEmpty(quote.quoteSummary.result[0].financialData.totalRevenue) ? '-' : quote.quoteSummary.result[0].financialData.totalRevenue.fmt;
const revGrowth = _isEmpty(quote.quoteSummary.result[0].financialData.revenueGrowth) ? '-' : quote.quoteSummary.result[0].financialData.revenueGrowth.raw * 100;
const earnGrowth = _isEmpty(quote.quoteSummary.result[0].financialData.earningsGrowth) ? '-' : quote.quoteSummary.result[0].financialData.earningsGrowth.raw * 100;
const freeCash = _isEmpty(quote.quoteSummary.result[0].financialData.freeCashflow) ? '-' : quote.quoteSummary.result[0].financialData.freeCashflow.fmt;
return [[divYield, payoutRatio, marketCap, fwdPE, revenue, revGrowth, earnGrowth, freeCash]];
}
}
function _isEmpty(obj) {
return Object.keys(obj).length === undefined;
}
请查看示例 sheet here(选项卡 JSON
)。
问题是:并非每个代码都有我从雅虎请求的每个 属性。我尝试了很多不同的方法来处理这个问题:
const payoutRatio = _isEmpty(quote.quoteSummary.result[0].summaryDetail.payoutRatio)
function _isEmpty(obj) {
return Object.keys(obj).length === undefined;
}
但是 none 这行得通。在示例 sheet 中,我试图提取股票代码 0P0001703K.SW
的数据,这是一种 ETF,因此它不会具有股票所具有的所有属性。 Google 张 return 错误:
#Error! TypeError: Cannot read property 'totalRevenue' of undefined (line 19).
它快把我逼疯了 :D 我一直在尝试以多种方式捕捉此类错误。我的问题是:检查 属性 是否存在的正确方法是什么,如果不存在,只需 return -
并继续下一个 属性?非常感谢您的帮助!
[编辑] 解决方案:
function _yahoofinance(ticker) {
const url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + encodeURI(ticker)
+ '?modules=price,assetProfile,summaryDetail,incomeStatementHistory,'
+ 'balanceSheetHistory,defaultKeyStatistics,financialData,calendarEvents,'
+ 'recommendationTrend,upgradeDowngradeHistory,majorHoldersBreakdown'
;
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const responseCode = response.getResponseCode();
if (responseCode === 200) {
const quote = JSON.parse(response.getContentText());
const price = quote.quoteSummary.result[0]?.price?.regularMarketPrice?.fmt || '-';
const divYield = quote.quoteSummary.result[0]?.summaryDetail?.dividendYield?.raw ? '-' : quote.quoteSummary.result[0].summaryDetail.dividendYield.raw * 100;
const payoutRatio = quote.quoteSummary.result[0]?.summaryDetail?.payoutRatio?.raw ? '-' : quote.quoteSummary.result[0].summaryDetail.payoutRatio.raw * 100;
const revenue = quote.quoteSummary.result[0]?.financialData?.totalRevenue?.fmt || '-';
return [[price, divYield, payoutRatio, revenue]];
}
}
您可以使用 optional chaining 而不是 _isEmpty()
函数,因为您检查 quote.quoteSummary.result[0].financialData.totalRevenue
是否为空但错误显示 'totalRevenue' of undefined。这意味着 financialData
是未定义的,它甚至在进入您的 isEmpty 函数之前就会抛出错误。
在您的示例中,它类似于:
const quote = {
quoteSummary: {
result: [{}]
}
}
const revenue = quote.quoteSummary.result?.[0]?.financialData?.totalRevenue?.fmt || '-';
console.log(revenue);