检查JSON属性是否存在

发布于 2025-01-29 20:03:36 字数 4203 浏览 2 评论 0 原文

I am importing stock JSON data from Yahoo Finance to import into Google Sheets for a personal stock tracker using a custom function:

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;
}

Please see an example sheet

问题是:并非每个股票都将拥有我从Yahoo请求的所有财产。我尝试以许多不同的方式来处理这一点:

const payoutRatio = _isEmpty(quote.quoteSummary.result[0].summaryDetail.payoutRatio)

function _isEmpty(obj) {
    return Object.keys(obj).length === undefined;
}

但是这些都没有作用。在示例表中,我试图在Ticker 0p0001703k.sw 上删除数据,这是ETF,因此它将没有库存的所有属性。 Google表返回一个错误:

#Error! TypeError: Cannot read property 'totalRevenue' of undefined (line 19).

这使我一半发疯了:DI一直在尝试以多种方式捕获此类错误。我的问题是:检查属性是否存在的正确方法是什么?您的帮助将不胜感激!

[编辑]解决方案:

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]];
  }
}

I am importing stock JSON data from Yahoo Finance to import into Google Sheets for a personal stock tracker using a custom function:

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;
}

Please see an example sheet here (tab JSON).

The problem is: not every ticker will have every property that I'm requesting from Yahoo. I have tried in many different ways to deal with this:

const payoutRatio = _isEmpty(quote.quoteSummary.result[0].summaryDetail.payoutRatio)

function _isEmpty(obj) {
    return Object.keys(obj).length === undefined;
}

But none of this works. In the example sheet I am trying to pull data on ticker 0P0001703K.SW, which is an ETF, so it will not have all the properties that stocks have. Google Sheets returns an error:

#Error! TypeError: Cannot read property 'totalRevenue' of undefined (line 19).

It is driving me half insane :D I have been trying to catch such errors in so many ways. My question is: what is the proper way to check if a property exists, and if not, just return - and move on to the next property? Your help would be greatly appreciated!

[EDIT] Solution:

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]];
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜空下最亮的亮点 2025-02-05 20:03:36

您可以使用 _isempty()函数,因为您检查 quote.quotesummary.result [0] .financialdata.totalrevenue 是空的>。这意味着 FinancialData 是未定义的,并且甚至在进入您的ISEMPTY函数之前就会引发错误。

在您的示例中,这将是:

const quote = {
  quoteSummary: {
    result: [{}]
  }
}
const revenue = quote.quoteSummary.result?.[0]?.financialData?.totalRevenue?.fmt || '-';
console.log(revenue);

You can use optional chaining instead of your _isEmpty() function because you check if quote.quoteSummary.result[0].financialData.totalRevenue is empty but error says 'totalRevenue' of undefined. That means that financialData is undefined and it throws error even before it goes to your isEmpty function.

In your example it would be something like:

const quote = {
  quoteSummary: {
    result: [{}]
  }
}
const revenue = quote.quoteSummary.result?.[0]?.financialData?.totalRevenue?.fmt || '-';
console.log(revenue);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文