简体   繁体   中英

secure method of access to non-existent properties

I'm using Google Apps Script with JavaScript code, running UrlFetchApp, to pull data from the Stripe API to retrieve an invoice. The Script then updates the data from the API into a Google Sheet template.

The problem I'm running into is if the API doesn't have data on a specific line for a customer it breaks the script. The API stores the lack of data as NULL, for example "discount": null when a customer has no discount on the invoice.

When the script hits the line with no data, the NULL response breaks the script and it stops running. What I want to do instead is return a value specifying that there's no data (ex: return the number 0 for no discount) and keep the script running through the remaining lines of code.

My code:

function getInvoiceObj() 
  {
    var apiKey, content, options, response, secret, url;

    secret = "rk_live_xxxxxxxxxxxxxxxxxx";
    apiKey = "xxxxxxxxxxxxxxxxx";

    url = "https://api.stripe.com/v1/invoices/in_xxxxxxxxxxxxx?expand[]=charge&expand[]=customer";

    options = {
      "method" : "GET",
      "headers": {
        "Authorization": "Bearer " + secret 
      },
      "muteHttpExceptions":true
    };

    response = UrlFetchApp.fetch(url, options);

    //Push data to Sheet from invoice. **Writes over existing Sheet data**
    content = JSON.parse(response.getContentText());
    var sheet = SpreadsheetApp.getActiveSheet();

     /* Customer Discount */

sheet.getRange(21,2).setValue([content.discount.coupon.percent_off]);
}

You might be looking for if

if(content.discount===null)
  sheet.getRange(21,2).setValue([0]);
else
  sheet.getRange(21,2).setValue([content.discount.coupon.percent_off]);

Perhaps ?:

sheet.getRange(21,2).setValue([
  content.discount===null?0:content.discount.coupon.percent_off
]);

This is a bit tricky and is subject for years from now, your problem is that coupon does not exists in discount so there is no way to get any value from undefined property (so the script breaks), there is several techniques to access properties from non-existing objects, like:

  • try...catch structure

     try { sheet.getRange(21,2).setValue([content.discount.coupon.percent_off]); } catch() { sheet.getRange(21,2).setValue([0]); } 
  • optional object passing

     const discountValue = ((content.discount || {}).coupon || {}).percent_off || 0; sheet.getRange(21,2).setValue([discountValue]); 
  • nested existence

     const discountValue = (content.discount && content.discount.coupon && content.discount.coupon.percent_off) || 0; sheet.getRange(21,2).setValue([discountValue]); 
  • some abstraction over property access

     const getPropertySafe = (props, object) => props.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, object) const value = getPropertySafe(['discount', 'coupon', 'percent_off'], content) sheet.getRange(21,2).setValue([value || 0]); 

Still, waiting for The Existential Operator anytime soon

content.discount?.coupon?.percent_off || 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM