Converting strings like document.cookie to objects

25,169

Solution 1

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);

Solution 2

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;
}, {});

Solution 3

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];
}

Solution 4

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);

Solution 5

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, "&")))
Share:
25,169
alexia
Author by

alexia

Updated on July 09, 2022

Comments

  • alexia
    alexia almost 2 years

    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;
    }
    
  • alexia
    alexia about 13 years
    That produces ['foo=bar', 'baz=quux'], but I need an object.
  • Nikita Rybak
    Nikita Rybak about 13 years
    @Nyuszika7H No, that produces an object and not array. You can't do result['foo'] on array.
  • Alnitak
    Alnitak about 13 years
    @Nyuszika7H - nope, this does exactly what you demanded, as does my very similar example.
  • alexia
    alexia about 13 years
    It isn't exactly correct, produces {'foo,bar': ['baz', 'quux']}.
  • Alnitak
    Alnitak about 13 years
    corrected - I forgot to use tmp instead of a in the last line.
  • alexia
    alexia about 13 years
    Sorry, I didn't see that the object is in the result variable. Thanks!
  • ShadSterling
    ShadSterling almost 8 years
    Note that this will fail if any of the "cookies" contain the cookie separator; this is probably not a problem, but could be if you use cookies for more complex data (such as in stackoverflow.com/questions/10119057).
  • sebilasse
    sebilasse about 7 years
    Please delete example 1 ! It is confusing because it returns a string ! See jsfiddle.net/pjja75hv
  • Kevin
    Kevin about 4 years
    code only answers are discouraged, you should explain what you are doing and why
  • Tobias Bergkvist
    Tobias Bergkvist about 3 years
    Or just do const [name, ...value] = current.split('='); prev[name] = value.join('=')
  • Dave
    Dave about 3 years
    You also need to remove the leading space, as in prev[name.slice(1)] = value.join('=')
  • undefined
    undefined over 2 years
    The suggested format is called entries (enumerable string-keyed property pairs). A shorter way to convert entries to an object is Object.fromEntries([['foo', 'bar'], ['baz', 'quux']])
  • undefined
    undefined over 2 years
    maybe for (let a of c) would be better. More readable and avoids creating a temporary i variable.
  • Alnitak
    Alnitak over 2 years
    @undefined that didn't exist in 2011.
  • undefined
    undefined over 2 years
    @Alnitak makes sense, didn't see it's 2011 at the time. I'll still keep the comment here so people know this functionality exists now