Google App Script - Mapping Error - TypeError: Property 'map' is not defined for this object

Thanks to the amazing insight from the community, I recently discovered this helpful tip on BatchUpdating background colors of a specific google sheet.

Excited to apply this to my own sheet, I encountered an error saying:

TypeError: Cannot read property 'map' of undefined

The code worked flawlessly in my test sheet, as shown below:

var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
   ranges:"TestBackgroundSheet!A1:AD39", fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
 });
 
 var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
                      .map(row => row["values"]
                      .map(value => value["effectiveFormat"]["backgroundColor"])); 

Upon copying and pasting the same code into my main project, which has a different SheetID, the same error persisted.

Despite following the same code structure with only a different SheetID, I repeatedly encounter the

TypeError: Cannot read property 'map' of undefined
Error.

Upon further investigation, the error seems to be centered around line 172 in the code:

.map(value => value["effectiveFormat"]["backgroundColor"]

Edit: https://i.sstatic.net/FSs6B.jpg

Edit #2:

While integrating Rafa's Code into mine, a new error surfaced: SyntaxError: Unexpected token , in JSON at position 1 (line 177, file "macros")

Here is the code snippet that led to the new error:

var TestArray = Sheets.Spreadsheets.get("1pcIKNUFmkk0d-UGg1sXl5xbsJC2WhocIHpM3et-CMgo", {
      ranges:"TestBackgroundSheet!A1:AD39",
      fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
    });
     
    var rowData = TestArray["sheets"][0]["data"][0]["rowData"]
    .map(row => row.getValues()).toString()
    
    var backgroundColors = JSON.parse("[" + rowData + "]")
    .map(value => {
         let v = value["effectiveFormat"]
         return v ? v["backgroundColor"] : null
         })

Edit #3:

Logging RowData with the following code snippet:

for (var x = 0; x < 40; x++) {
      Logger.log(x + JSON.stringify(TestArray["sheets"][0]["data"][0]["rowData"][x]));
    }

Upon analysis, it seemed that the issue lied in the initial stages of the Logger statements. In the "Testing Sheet", even empty rows returned with a full White background color (RGB {"green":1,"red":1,"blue":1}), whereas in the "Real Sheet", 3 out of the first 4 lines produced an empty object. Below are the first four lines from the output, highlighting the discrepancy between the two sheets.

Actual:

[20-10-21 08:53:23:591 EDT] 0{}
[20-10-21 08:53:23:593 EDT] 1{"values":[{},{"effectiveFormat":{"backgroundColor":{"green":1,"blue":1,"red":1}}}]}
[20-10-21 08:53:23:595 EDT] 2{}
[20-10-21 08:53:23:597 EDT] 3{}

Testing:

[20-10-21 05:53:14:167 PDT] 0{"values":[{"effectiveFormat":{"backgroundColor":{"green":1,"red":1,"blue":1}}},{"effectiveFormat":{"backgroundColor":{"red":1,"blue":1,"green":1}}},{"effectiveFormat":{"backgroundColor":{"green":1,"red":1,"blue":1}}},{"effectiveFormat":{"backgroundColor":{"red":1,"green":1,"blue":...

Answer №1

Solution:

It's important to note that not all elements in row["values"] contain data. Therefore, running

.map(value => value["effectiveFormat"]["backgroundColor"])
on rows without data will result in errors.

Insight:

After retrieving data from the API using

Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg")

and applying a field mask filter, the response will contain all information from the sheet, including cells without background color data. You cannot map each row in this scenario since attempting to access the effectiveFormat element on empty cells will fail.

Solution:

To address this issue, you can use the ternary operator. If value["effectiveFormat"] is missing, simply return null:

var rowData = TestArray["sheets"][0]["data"][0]["rowData"]
    .map(row => row.getValues()).toString()

var backgroundColors = JSON.parse("[" + rowData + "]")
    .map(value => {
        let v = value["effectiveFormat"]
        return v ? v["backgroundColor"] : null
    })

Note: The API may contain functions within JSON objects, which can be utilized in Apps Script. Directly referencing row["values"] may return functions rather than data:

console.log(TestArray["sheets"][0]["data"][0]["rowData"]
            .map(row => row["values"]))

above code returns:

[ 
  { 
    setPivotTable: [Function],
    getDataSourceTable: [Function],
    ...
  },
  ...
]

Using toString() after the initial mapping helps extract data before proceeding with the second mapping function.

Additional Resources:

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

Split a string into chunks at every odd and even index

I have limited knowledge of javascript. When given the string "3005600008000", I need to devise a method that multiplies all the digits in the odd-numbered positions by 2 and those in the even-numbered positions by 1. This code snippet I drafted seems to ...

Executing a get request in Backbone without using the Option parameter by implementing the beforeSend method

After gathering insights from the responses to this and this queries, I have formulated the code below for a GET request: var setHeader = function (xhr) { xhr.setRequestHeader("Authorization", "Basic " + btoa($rootScope.login.Gebruikersnaam + ":" + $r ...

Preserve the specific date and time in the designated timezone

Utilizing the react-datePicker library requires using new Date() as input. I need to save the user's selected date, time, and timezone in such a way that regardless of their location, they will see Feb 10 2024 02:00 BST in the Date Object. Currently, ...

Encountered an issue while attempting to start an SSR server with inertiajs

I followed all the necessary steps to set up an ssr application, but unfortunately, I am encountering some difficulties. config/inertia export const inertia: InertiaConfig = { view: 'app', ssr: { enabled: true, autoreload: process.en ...

Assistance needed with utilizing jQuery for checkboxes and arrays

Greetings! I am struggling to retrieve the names and values of checked checkboxes and store them in an array named selected. Despite several attempts, I have not been able to get it working as intended. Below is my code snippet, any assistance in identif ...

The oninput() event does not trigger on phones and tablets

Currently, I am in the process of developing an application using PhoneGap. An issue has arisen where my code runs perfectly fine when tested on a browser, but the onInput() function does not seem to trigger on mobile devices. <div class="t1">09< ...

Is there a way to verify that a form field has been completed?

Currently, I am grappling with a method to clear a field if a specific field is filled in and vice versa. This form identifies urgent care locations based on the information provided by users. The required entries include the name of the urgent care facil ...

One way to eliminate a prefix from a downloaded file path is by trimming the URL. For example, if you have a URL like "http://localhost

As my web app runs on port number, I am looking to download some files in a specific section. However, the download file path is being prefixed with "". <a href={file_path} download={file_name}> <Button variant={"link"}> <b>Dow ...

Is there a way to create a nested object literal that will return the length of

I am working with JSON data that includes different locations (sucursales) and cars for each location. How can I write a function to calculate the total number of cars across all locations? [{"sucursal": "Quilmes", "direccion&q ...

implementing automatic ajax requests when user scrolls

This is a piece of JavaScript code: $(window).scroll(function() { $.ajax({ type: "GET", url: "not_data.php", data: dataString, success: function my_func () { //show new name ...

Changing the ng-src attribute with a custom service in an AngularJS application

Check out this Pluker I created for making image swapping easier. Currently, the images swap normally when coded in the controller. However, I am interested in utilizing custom services or factories to achieve the same functionality. Below is the code snip ...

Incorporating Microsoft's Emotion API into an HTML website

Currently, I am attempting to develop a HTML webpage that can detect emotions from images submitted by the user. By referring to Microsoft's documentation, I have produced the following HTML file: <!DOCTYPE html> <html> <head> & ...

Incorporate a SharpSpring form within a custom React component

Trying to integrate a Sharpspring form script into my React component (page.jsx). The form needs to be placed outside the <head></head> element and inside the <div> where I want to display it. The original HTML code for embedding the for ...

Encountering a Meteor issue during the installation of npm packages

When attempting to install cheerio through npm, I encountered a specific error message. Error: Can't set DOCTYPE here. (Meteor sets <!DOCTYPE html> for you) - line 1, file Similarly, when trying to use jsdom, I faced a parse error. Currently ...

Trouble with the x-cloak attribute in alpine.js

Experience with TailwindCSS and AlpineJS in my current project has brought to my attention a slight issue with the header dropdowns flashing open momentarily when the login page loads. I attempted to use x-cloak to address this, but encountered some diffic ...

I am looking to incorporate a dropdown feature using Javascript into the web page of my Django project

According to the data type of the selected column in the first dropdown, the values displayed in the columns of the second dropdown should match those listed in the JavaScript dictionary below, please note: {{col.1}} provides details on the SQL column data ...

Effective implementation of the useReducer hook across various React components to manage form state

My current project is proving to be quite challenging as I navigate through the step-by-step instructions provided. Initially, I was tasked with creating a BookingForm.js component that houses a form for my app. The requirement was to utilize the "useEffec ...

Having trouble accessing variables from the dotenv file in a NextJS project

Recently, I started using Next.js and ran into a bit of trouble. Here's the issue: When I'm in the connectToMongo function, my variable is coming through just fine. However, when I switch over to Main/index.tsx, my process.env appears as an emp ...

Is it possible to retrieve the final digit from a URL using NUXT/Vue?

My dilemma involves utilizing the SWAPI API to display a single result, whether it be a person or a planet. However, instead of providing a direct ID for each item, the API returns a complete URL in this format: "url": "http://swapi.dev/api/ ...

How come I am receiving {"readyState":1} in the DOM instead of JSON data in AngularJS?

Currently, I am facing an issue where instead of the JSON data (which consists of only 49 items) showing up on the DOM, I am getting {"readyState":1}. I believe this is just a test to ensure that my code is functioning correctly. Although I have identifie ...