a reliable approach to gain entry to properties that do not exist

Utilizing Google Apps Script along with JavaScript code, I am leveraging UrlFetchApp to retrieve data from the Stripe API in order to fetch an invoice. Subsequently, the Script processes the retrieved data and updates a Google Sheet template with it.

An issue that I am currently facing is that when the API does not contain information for a specific field related to a customer, the script encounters errors. The API indicates this absence of data as NULL; for instance, "discount": null might denote that a customer has no discount on the invoice.

Whenever the script encounters a line containing no data (NULL response), it breaks and ceases to execute further. My objective is to modify the behavior such that if there is no data available, the script should continue running and return a specified value denoting the absence of data (such as returning 0 for no discount) instead.

Here is the snippet of 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. **Overwrites existing Sheet data**
    content = JSON.parse(response.getContentText());
    var sheet = SpreadsheetApp.getActiveSheet();

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

Answer №1

Are you in need of the if statement?

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

Maybe consider using ?:

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

Answer №2

This situation can be a bit complex and may remain relevant for years to come. The issue lies in the fact that coupon is not present within discount, making it impossible to retrieve any value from a nonexistent property, thus causing the script to break. However, there are several methods available to handle properties within non-existing objects:

  • Utilizing a try...catch structure

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

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

    const discountValue = (content.discount && content.discount.coupon && content.discount.coupon.percent_off) || 0;
    sheet.getRange(21,2).setValue([discountValue]);
    
  • Creating abstractions for 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]);
    

Anticipating the arrival of The Existential Operator at some point in the future

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing the ajax request to not go through?

Check out this function I created that triggers an event when any inputs in an HTML form are changed. Function Snippet: function customEvent(form, element) { var timer; $(element).keyup(function () { clearTimeout(timer); if ($(ele ...

How can I adjust the time in a range slider using AngularJS?

Currently, I am utilizing a Slider with draggable range in angular js for time selection. The Slider can be found here: https://jsfiddle.net/ValentinH/954eve2L/. I aim to configure the time on this slider to span from 00.00 to 24.00, with a 10-minute inter ...

Determining the duration since generating a unique objectid in mongodb

I am currently developing an application that offers users the option to reset their passwords. The process is quite straightforward - after entering his email address, the user will receive a link containing the new objectid number. For example: /reset- ...

The module 'safe-buffer' is not found by NPM

Ever since installing yarn, I've been unable to use npm. The upgrade for NodeJS went smoothly. Trying to remove npm is proving impossible. Every command I attempt results in the same error message: module.js:487 throw err; ^ Error: Cannot f ...

Sending a blob through AJAX to a different domain using CORS

Could someone please explain why my current request is being blocked by the SO policy restriction? Javascript Code: var blob = new Blob([req.response], {type: "application/octet-stream"}); req = new XMLHttpRequest(); req.open("POST", ws_path(other_contex ...

How come when you add ({}+{}) it equals to "[object Object][object Object]"?

I ran the following code: {}+{} = NaN; ({}+{}) = "[object Object][object Object]"; What is the reason behind the difference in result when adding ()? ...

EJS unable to display template content

I am having an issue with rendering a template that contains the following code block: <% if(type === 'Not Within Specifications'){ %> <% if(Length !== undefined) { %><h5>Length: <%= Length %> </h5> <% ...

An uncaught exception has occurred: An error was encountered indicating that the specified path is not valid for either posix or windows systems, and it appears that there is no 'join' method defined in the

I am currently working with nextjs version 13.5.6 using the app router and app directory. This issue arises during the compilation of the route app/(home)/page.js. The folder and file structure within the app folder is as follows: app/ -(home)/page.js -ser ...

Receiving Request URL from XMLHttpRequest in PHP

I'm currently facing a dilemma as I work on a JavaScript script that is responsible for sending data from one of my forums to the server where a PHP script runs. The goal is to have the PHP script determine which JS output should be generated based on ...

What is the best way to create a div that extends beyond the borders of the screen, but still allows only

I am currently working on a React project for a website. I am creating a category bar that should slide only the component in the mobile version, without moving the entire page. Check out the desired design here However, the current appearance is differe ...

How can I load only specific images on a webpage using HTML?

I attempted to implement an image filter for my website by using the code below: <script> function myFunction() { // Initialize variables var input, filter, ul, li, a, i; input = document.getElementById('myInput'); filter = input.value.toU ...

What is the reason that when the allowfullscreen attribute of an iframe is set, it doesn't appear to be retained?

Within my code, I am configuring the allowfullscreen attribute for an iframe enclosed in SkyLight, which is a npm module designed for modal views in react.js <SkyLight dialogStyles={myBigGreenDialog} hideOnOverlayClicked ref="simpleDialog"> <if ...

Enhance your Next JS website's SEO with a combination of static pages, SSR pages, and client-side

In my project using Apollo GraphQL with Next JS, I have explored three different approaches to querying and rendering data. The first method involves Static Rendering by utilizing getStaticProps(), which looks like the following: export async function getS ...

Attempting to showcase extensive content based on the selection made in a drop-down menu

As a newcomer to anything beyond basic HTML, I am seeking guidance and assistance (preferably explained at a beginner level) for the following issue. If I have overlooked any crucial rules or concepts in my query, I apologize. I aim to have each selection ...

What is the mechanism behind the operation of asynchronous functions within the bcrypt() method in Node.js?

const bcrypt = require('bcrypt'); const saltRounds = 8; const plainPassword1 = "12345"; const plainPassword2 = "56789"; const func1 = async (password, plainP) => { console.log("hashing password"); const h ...

Issue with IE7: jQuery.getJSON callback not triggering

A legitimate JSON file, returned with the correct HTTP headers: Content-Type:application/json; charset= Displays properly in Chrome/FF, but IE7 is having trouble parsing it. Where should I start investigating? $.getJSON(url, null, function(data){ aler ...

Improving large JSON data with multiple calls

In my Java/Spring web application, I have implemented a feature where each user can manage their own word list. Whenever a user adds or removes a word, an AJAX call is made to send a JSON object with the word information to the server for processing. The s ...

Tips on efficiently storing JSON objects into an array using PHP

Below is my PHP code used to retrieve data in JSON format: if($status==1) { $post_id=$json_object['post_id']; $get_postid=mysqli_query($con,"select * from User_Post where post_id='$post_id'"); if(mysqli_nu ...

Challenges arise when utilizing CSS3 animations in conjunction with transitions triggered by toggling a JavaScript class

Struggling to activate an animation while updating a class using JavaScript for a PhoneGap app. Planning on utilizing -webkit- prefixes for compatibility. However, the animations are currently unresponsive in Chrome during testing, both when applied to th ...

Issue with Yup and Formik not validating checkboxes as expected

I'm struggling to figure out why the validation isn't functioning as expected: export default function Check() { const label = { inputProps: { "aria-label": "termsOfService" } }; const formSchema = yup.object().shape({ ...