user492203
user492203

Reputation:

Converting strings like document.cookie to objects

I have a string similiar to document.cookie:

var str = 'foo=bar, baz=quux';

Converting it into an array is very easy:

str = str.split(', ');
for (var i = 0; i < str.length; i++) {
    str[i].split('=');
}

It produces something like this:

[['foo', 'bar'], ['baz', 'quux']]

Converting to an object (which would be more appropriate in this case) is harder.

str = JSON.parse('{' + str.replace('=', ':') + '}');

This produces an object like this, which is invalid:

{foo: bar, baz: quux}

I want an object like this:

{'foo': 'bar', 'baz': 'quux'}

Note: I've used single quotes in my examples, but when posting your code, if you're using JSON.parse(), keep in your mind that it requires double quotes instead of single.


Update

Thanks for everybody. Here's the function I'll use (for future reference):

function str_obj(str) {
    str = str.split(', ');
    var result = {};
    for (var i = 0; i < str.length; i++) {
        var cur = str[i].split('=');
        result[cur[0]] = cur[1];
    }
    return result;
}

Upvotes: 21

Views: 38176

Answers (13)

Nikita Rybak
Nikita Rybak

Reputation: 68026

Why exactly do you need JSON.parse in here? Modifying your arrays example

let str = "foo=bar; baz=quux";

str = str.split('; ');
const result = {};
for (let i in str) {
    const cur = str[i].split('=');
    result[cur[0]] = cur[1];
}


console.log(result);

Upvotes: 13

Joseph Merdrignac
Joseph Merdrignac

Reputation: 3860

parse cookies (IE9+):

document.cookie.split('; ').reduce((result, v) => {
  const k = v.split('=');
  result[k[0]] = k[1];
  return result;
}, {})

Upvotes: 2

n4ly
n4ly

Reputation: 51

A way to parse cookies using native methods like URLSearchParams and Object.fromEntries, avoiding loops and temporary variables.

Parsing document.cookie:

Object.fromEntries(new URLSearchParams(document.cookie.replace(/; /g, "&")))

For the scope of the question (cookies are separated by , and stored in variable str)

Object.fromEntries(new URLSearchParams(str.replace(/, /g, "&")))

Upvotes: 5

user3114190
user3114190

Reputation:

The shortest way

 document.cookie.split('; ').reduce((prev, current) => {
    const [name, ...value] = current.split('=');
    prev[name] = value.join('=');
    return prev;
  }, {});

Upvotes: 36

LelilolZH
LelilolZH

Reputation: 109

function getCookie(){
   var o=document.cookie.split("; ");
   var r=[{}];
   for(var i=0;i<o.length;i++){
      r[o[i].split("=")[0]] = o[i].split("=")[1];
   }
   return r;
}

Just call getCookie() and it will return all cookies from the current website. If you have a cookie called 'mycookie' you can run getCookie()['mycookie']; and it will return the value of the cookie 'mycookie'. There is also a One-Line option:

function getCookie(){var o=document.cookie.split("; ");var r=[{}];for(var i=0;i<o.length;i++){r[o[i].split("=")[0]] = o[i].split("=")[1];}return r;}

This one can be used with the same methods as above.

Upvotes: 0

Dave
Dave

Reputation: 708

Most of the above solutions fail with the __gads cookie that Google sets because it uses a '=' character in the cookie value.

The solution is to use a regular expression instead of calling split('='):

document.cookie.split(';').reduce((prev, current) => {
  const [name, value] = current.split(/\s?(.*?)=(.*)/).splice(1, 2);
  prev[name] = value;
  return prev;
}, {});

Upvotes: 0

killovv
killovv

Reputation: 111

first thing that occurred to me, I'll leave it as the original version, but cookies should not be empty otherwise there will be a json parse error

JSON.parse(`{"${document.cookie.replace(/=/g,'":"').replace(/; /g,'","')}"}`)

fast and reliable version - cookie to object

let c=document.cookie.split('; '),i=c.length,o={};
while(i--){let a=c[i].split('=');o[a[0]]=a[1]}

and short function for get single cookie

getCookie=e=>(e=document.cookie.match(e+'=([^;]+)'),e&&e[1])

Upvotes: 1

sebilasse
sebilasse

Reputation: 4618

note : The document.cookie (question headline) is semicolon separated and not comma separated (question) ...

An alternative using reduce :

var str = 'foo=bar; baz=quux';
var obj = str.split(/[;] */).reduce(function(result, pairStr) {
  var arr = pairStr.split('=');
  if (arr.length === 2) { result[arr[0]] = arr[1]; }
  return result;
}, {});

Upvotes: 5

Neil Monroe
Neil Monroe

Reputation: 1190

An alternate version of your updated solution that checks for the null/empty string and just returns an empty object and also allows for custom delimiters.

function stringToObject(str, delimiter) {
    var result = {};
    if (str && str.length > 0) {
        str = str.split(delimiter || ',');
        for (var i = 0; i < str.length; i++) {
            var cur = str[i].split('=');
            result[cur[0]] = cur[1];
        }
    }
    return result;
}

Upvotes: 0

Andy E
Andy E

Reputation: 344713

I'm a fan of John Resig's "Search and don't replace" method for this sort of thing:

var str = 'foo=bar, baz=quux',
    arr = [],
    res = '{';

str.replace(/([^\s,=]+)=([^,]+)(?=,|$)/g, function ($0, key, value) { 
    arr.push('"' + key + '":"' + value + '"');
});

res += arr.join(",") + "}";

alert(res);

Working example: http://jsfiddle.net/cm6MT/.

Makes things a lot simpler without the need for JSON support. Of course, it's just as easy to use the same regular expression with exec() or match().


Whoops, I thought you wanted to convert to a JSON string, not an object. In that case, you only need to modify the code slightly:

var str = 'foo=bar, baz=quux',
    res = {};

str.replace(/([^\s,=]+)=([^,]+)(?=,|$)/g, function ($0, key, value) { 
    res[key] = value;
});
console.log(res.foo);
//-> "bar"

Working example 2: http://jsfiddle.net/cm6MT/1/

Upvotes: 0

Chad
Chad

Reputation: 9859

That's pretty crappy data, as long as its not using ,= this would work on that data

var text = 'foo=bar, baz=quux',
    pattern = new RegExp(/\b([^=,]+)=([^=,]+)\b/g),
    obj = {};

while (match = pattern.exec(text)) obj[match[1]] = match[2];

console.dir(obj);

Upvotes: 0

ircmaxell
ircmaxell

Reputation: 165281

To convert it to an object, just do that from the beginning:

var obj = {};
str = str.split(', ');
for (var i = 0; i < str.length; i++) {
    var tmp = str[i].split('=');
    obj[tmp[0]] = tmp[1];
}

Then, if you want JSON out of it:

var jsonString = JSON.stringify(obj);

Upvotes: 1

Alnitak
Alnitak

Reputation: 339975

Given an array a containing your intermediate form:

[['foo', 'bar'], ['baz', 'quux']]

then simply:

var obj = {};
for (var i = 0; i < a.length; ++i) {
   var tmp = a[i];
   obj[tmp[0]] = tmp[1];
}

Upvotes: 2

Related Questions