1
\$\begingroup\$

I have a cookie on my site with the following value:

eyJGIjp0cnVlLCJBIjp0cnVlLCJUIjpmYWxzZSwiUyI6ZmFsc2UsIkciOmZhbHNlLCJYIjpmYWxzZX0%3D

I use this function to retrieve the value from the site so I can use it in the applications my site uses to greenlight certain elements or to block them.

function getCookieLawSettings() {
    return document.cookie.split(';')
            .map(c => c.trim().split('='))
            .filter(c => c.shift() == 'cookie_law')
            .map(c => JSON.parse(atob(decodeURIComponent(c.pop())))).pop()
}

What kind of improvements could I make on this code? Stylistic and functional.
Are there things I missed/gotcha's I should account for?

sample with dummy data:

document.not_cookie = "_ga=GA1.2.431922604.1523436815; _gid=GA1.2.1579280874.1523436815; cookie_law=eyJGIjp0cnVlLCJBIjp0cnVlLCJUIjpmYWxzZSwiUyI6ZmFsc2UsIkciOmZhbHNlLCJYIjpmYWxzZX0%3D";
function getCookieLawSettings() {
    return document.not_cookie.split(';')
            .map(c => c.trim().split('='))
            .filter(c => c.shift() == 'cookie_law')
            .map(c => JSON.parse(atob(decodeURIComponent(c.pop())))).pop()
}
console.log(getCookieLawSettings());

\$\endgroup\$
3
\$\begingroup\$

Since (I assume) there should only be a single cookie fragment called cookie_law you should use find instead of filter. filter will go through the whole array even if the result is the first element.

As it stands I think that it is bad for a filter method to modify the underlying data.

Also the number of parenthesis in the line

.map(c => JSON.parse(atob(decodeURIComponent(c.pop())))).pop()

is pretty scary. I would pull at least some of that out into another method.

update

In my code I usually split out my logic with a method to get any cookie, that way I can reuse it for other cookies. The logic also ends up being simpler.

function getCookieLawSettings() {
    return decodeCookie(getCookie('cookie_law'));
}

function getCookie(na,e) {
    var cookie = document.cookie.split(';')
            .map(c => c.trim().split('='))
            .filter(c => c[0] === name);
    return cookie ? cookie[1] : undefined;
}

function decodeCookie(data) {
    return JSON.parse(atob(decodeURIComponent(data)));
}

function encodeCookie(data) {
    return btoa(encodeURIComponent(JSON.stringify)));
}
\$\endgroup\$
3
  • \$\begingroup\$ The parenthesis is wat led me to post here too. Looked too lispy for my tastes. Just run it through a second map? The find suggestion is a good one. Didn't think of that. And yea, it's just for that specific cookie. I base64 encoded it because urlencoded json was three times as long. Decoding it is how i ended up with the parenthesises. \$\endgroup\$ – Tschallacka Apr 13 '18 at 21:39
  • \$\begingroup\$ @Tschallacka You can just define a decodeCookie() function (analogously encodeCookie()), so that you run .map(decodeCookie). I'd also replace .shift() and .pop() calls by immutable operations, e.g. just array indexing [0]. \$\endgroup\$ – ComFreek Apr 14 '18 at 15:30
  • \$\begingroup\$ You could use an extra map to replace c.pop() but if you use find you would have a single element not an array so you would no longer be able to use map. \$\endgroup\$ – Marc Rohloff Apr 14 '18 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.