Home > Software design >  Uncaught Type Error for First Object in Multidimensional Array, but Can Still Print to Console
Uncaught Type Error for First Object in Multidimensional Array, but Can Still Print to Console

Time:07-27

I'm sure there's a simple solution to this, so I feel like a buffoon asking for help. I'm just stuck.

My design intent is to capture UTM data and store it in local storage for later use in a web form (posting to salesforce). I'm trying to loop over a multidimensional array and get the values, namely a parameter name (the UTM string name to parse from the URL) and an id (to get the field in the form later).

I loop over the array by the length using for - and it correctly collects the ID but not the name, which throws the following error: (index):411 Uncaught TypeError: Cannot read properties of undefined (reading 'paramName') at addUtm ((index):411:42).

What's bizarre is if use the console, I can grab the value with the index.

Full script below:

<script>


function getParam(p) {
      var match = RegExp("[?&]"   p   "=([^&]*)").exec(window.location.search);
      return match && decodeURIComponent(match[1].replace(/\ /g, " "));
}

function getExpiryRecord(value) {
  var expiryPeriod = 90 * 24 * 60 * 60 * 1000; // 90 day expiry in milliseconds

  var expiryDate = new Date().getTime()   expiryPeriod;
  return {
    value: value,
    expiryDate: expiryDate
  };
}

var paramsJSON = [
   {
       paramName: "utm_source",
       id: "00N6g00000NiGFS"
   },   
   {
       paramName: "utm_medium",
       id: "00N6g00000NiGFQ"
   },   
   {
       paramName: "utm_campaign",
       id: "00N6g00000NiGFN"
   }
]

console.log(paramsJSON)
function addUtm() {
  for (i=0; paramsJSON.length; i  ){
    
    var utmName = getParam(paramsJSON[i].paramName); // OFFENDING LINE!
    console.log('UTM name: '   utmName);
    var utmId = paramsJSON[i].id;
    console.log('UTM id: '  utmId);
    var utmRecord = null;
    var currUtmFormField;

    var gclsrcParam = getParam('gclsrc');
    var isGclsrcValid = !gclsrcParam || gclsrcParam.indexOf('aw') !== -1;

    if (document.getElementById(utmId)) {
      currUtmFormField = document.getElementById(utmId);
    }
 
    if (utmName && isGclsrcValid) {
      utmRecord = getExpiryRecord(utmName);
      console.log(utmRecord)
      localStorage.setItem(utmName, JSON.stringify(utmRecord));
    }

    var utm = utmRecord || JSON.parse(localStorage.getItem(utmName));
    console.log('UTM: '   utm);
    var isUtmValid = utm && new Date().getTime() < utm.expiryDate;

    if (currUtmFormField && isUtmValid) {
      currUtmFormField.value = utm.value;
      console.log('UTM value: '  utm.value);
    }
  }
}

window.addEventListener('load', addUtm);

 </script>

I put a comment in the script for the offending line:

var utmName = getParam(paramsJSON[i].paramName); // OFFENDING LINE! . I'm sure I'm missing something obvious but any help would be greatly appreciated. I've searched for out-of-the-box solutions for this but come up a bit short, as I'm inexperienced with Javascript. If it makes a difference (not sure it does), I'm running this in WordPress. Below is what I see in the console.

enter image description here

What is causing paramName to return null?

CodePudding user response:

Here is a working version

I had to mock the URL and the localStorage parts. You can change

const loc = "https://bla.com/page?utm_source=source&utm_medium=medium&utm_campaign=campaign"; 
const url = new URL(loc || window.location.href)

to

const url = new URL(window.location.href)

when on your server, change

var lsUtm = "{}"; // localStorage.getItem(utmName);

to

var lsUtm = localStorage.getItem(utmName); 

and uncomment

// localStorage.setItem(utmName, JSON.stringify(utmRecord));

const loc = "https://bla.com/page?utm_source=source&utm_medium=medium&utm_campaign=campaign"; 
const url = new URL(loc || window.location.href)
function getParam(p) {
  return url.searchParams.get(p)
}

function getExpiryRecord(value) {
  var expiryPeriod = 90 * 24 * 60 * 60 * 1000; // 90 day expiry in milliseconds

  var expiryDate = new Date().getTime()   expiryPeriod;
  console.log("ex", {
    value: value,
    expiryDate: expiryDate
  })
  return {
    value: value,
    expiryDate: expiryDate
  };
}

var paramsJSON = [{
    paramName: "utm_source",
    id: "00N6g00000NiGFS"
  },
  {
    paramName: "utm_medium",
    id: "00N6g00000NiGFQ"
  },
  {
    paramName: "utm_campaign",
    id: "00N6g00000NiGFN"
  }
]

function addUtm() {
  for (let i = 0; i < paramsJSON.length; i  ) {
    console.log("pname",paramsJSON[i].paramName)
    var utmName = getParam(paramsJSON[i].paramName); 
    var utmId = paramsJSON[i].id;
    console.log('UTM name:', utmName,'UTM id:', utmId);
    var utmRecord = null;
    var currUtmFormField = document.getElementById(utmId);

    var gclsrcParam = getParam('gclsrc');
    var isGclsrcValid = !gclsrcParam || gclsrcParam.indexOf('aw') !== -1;

    if (utmName && isGclsrcValid) {
      utmRecord = getExpiryRecord(utmName);
      console.log(utmRecord)
     // localStorage.setItem(utmName, JSON.stringify(utmRecord));
     console.log("LS",utmName, JSON.stringify(utmRecord)); // SO does not like localStorage
    }
    var lsUtm = "{}"; // localStorage.getItem(utmName)
    var utm = utmRecord || JSON.parse(lsUtm); 
    console.log('UTM: ', utm);
    var isUtmValid = utm && new Date().getTime() < utm.expiryDate;
console.log(isUtmValid)
    if (currUtmFormField && isUtmValid) {
      currUtmFormField.value = utm.value;
      console.log('UTM value: '   utm.value);
    }
  }
}

window.addEventListener('load', addUtm);
<input id="00N6g00000NiGFS" value="">
<input id="00N6g00000NiGFQ" value="">
<input id="00N6g00000NiGFN" value="">

  • Related