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.
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="">