6

I am tracking URLs with "posName" parameters like:

example.com?posName=Content+&+Community+Manager+(H/F)

But my code returns "Content" only:

function () {
    var uri = document.location.href;
    var uri_dec = decodeURIComponent(uri);
    var url = new URL(uri_dec);
    var posName= url.searchParams.get("posName");
    return posName;
}

How can I get the full parameter?

EDIT: I have another URL like:

exemple.com?posName=Club+&+Animator+(H/F)

And the code returns the full parameter... So is it the length of the parameter which causes this issue?

Boann
  • 48,794
  • 16
  • 117
  • 146
B4b4j1
  • 430
  • 2
  • 7
  • 24
  • 2
    Well that's an invalid URI - you'd need to encode the `&` where you're sending the data like `%26`. – Jack Bashford May 22 '19 at 00:04
  • 1
    Try to follow the example in https://www.w3schools.com/jsref/jsref_decodeuricomponent.asp – Mulli May 22 '19 at 00:09
  • Good point... Is it possible to encode 1 element of the url only ? – B4b4j1 May 22 '19 at 00:19
  • I tried another approach with regex : var regex = (/(?=posName=)(.*)&/g) // var posName = uri.match(regex).... but it is returning undefined. – B4b4j1 May 22 '19 at 00:28

2 Answers2

5

I've modified your function to accept the URI as an argument. You need to encode the parameter before appending it to the query string (we can't see this code here). The decodeURIComponent in your function is also not necessary.

function getPosName (URI) {
    //var uri_dec = decodeURIComponent(uri);
    var url = new URL(URI);
    var posName = url.searchParams.get("posName");
  return posName;
}

console.log("Using your current URI:", getPosName("http://exemple.com?posName=Content+&+Community+Manager+(H/F)"))

const encodedParam = encodeURIComponent("Content & Community Manager (H/F)")
console.log("Encoded Parameter:", encodedParam)
const wellFormedURI = `http://exemple.com?posName=${encodedParam}`
console.log("Well Formed URI:", wellFormedURI)
console.log("Using well formed URI:", getPosName(wellFormedURI))
BlueWater86
  • 1,773
  • 12
  • 22
1

If for some reason you have no control over what's in the window.location.href, you can solve this quite easily via regex:

function getPosName(uri) {
    let match = uri.match(/(?<=posName=)(.+?)(?=\&\w+?\=|$)/); 
    return match[1]; 
}

console.log(getPosName( "xemple.com?posName=Content+&+Community+Manager+(H/F)")); //Content+&+Community+Manager+(H/F)
console.log(getPosName( "exemple.com?posName=Club+&+Animator+(H/F)")); //Club+&+Animator+(H/F)
console.log(getPosName( "exemple.com?posName=Club+&+Animator+(H/F)&test=1")); // Club+&+Animator+(H/F)

Regex explanation:

(?=postName=) lookbehind to find postName= to start the match

(.+?) matches anything up to the lookahead pattern below

(?=\&\w+?\=|$) loohahead pattern for literal & followed by some text of any length from 1 onwards \w+? followed by =. All that, or we're at the end of the input string, denoted by $

Update

The regex lookbehind is relatively new. If the browser or app doesn't support the regex lookbehind (e.g. Google Tag Manager currently), try this workaround instead:

function getPosName(uri) {
    let match = uri.match(/posName=(.+?)(?=\&\w+?\=|$)/);
    return match[1];
}

console.log(getPosName( "xemple.com?posName=Content+&+Community+Manager+(H/F)")); //Content+&+Community+Manager+(H/F)
console.log(getPosName( "exemple.com?posName=Club+&+Animator+(H/F)")); //Club+&+Animator+(H/F)
console.log(getPosName( "exemple.com?posName=Club+&+Animator+(H/F)&test=1")); // Club+&+Animator+(H/F)
Community
  • 1
  • 1
chatnoir
  • 2,185
  • 1
  • 15
  • 17
  • Nice regex... however when using it with a script in Google tag Manager, it returns this error : ": Cannot convert ECMASCRIPT_2018 feature "RegExp Lookbehind" to targeted output language." Is GTM not accepting new regex features ? – B4b4j1 May 22 '19 at 10:01
  • 1
    While waiting for GTM to upgrade, we can use the workaround in my updated answer :D – chatnoir May 22 '19 at 10:24
  • Thanks.. i needed to adapt a little bit for GTM ("var" instead of "let") but it works fine ! – B4b4j1 May 22 '19 at 12:01