0

I'm calling in data from the Google Sheets API, and each row's content looks like this:

 {
   $t: "title: Test Title, gamelabel: Test Game, startdate: 2016-06-14"
 }

Is there any off-the-shelf / easy way to turn this string into a javascript object in this format?

{
 title : 'Test Title',
 gamelabel: 'Test Game',
 startdate: '2016-06-14
}

Note, the keys need to be dynamic (creating keys for whatever the sheets' heading is), so knowing exactly what keys will be in $t isn't possible.

Update: Using JSON.parse() doesn't work here, I suppose there's a hacky-ish way of doing this via:

 var temp = {};
 var params = $t.split(/:/g);
 for(var i = 0; i<params.length; i += 2){
  temp[params[i].trim()] = params[i + 1].trim(); 
 }

This doesn't actually work for the supplied format / is potentially a start but I dunno what's the best practice here.

JVG
  • 20,198
  • 47
  • 132
  • 210
  • 1
    @RobG: No; that isn't JSON. – SLaks May 31 '16 at 02:41
  • That looks like a job for `eval()` – Leo supports Monica Cellio May 31 '16 at 02:41
  • I edited in a semi-code sample into the question – JVG May 31 '16 at 02:49
  • check here http://stackoverflow.com/questions/45015/safely-turning-a-json-string-into-an-object – Ari May 31 '16 at 02:52
  • How are commata escaped in the field values? – Bergi May 31 '16 at 02:54
  • According to https://developers.google.com/sheets/samples/reading#read_a_single_range returned data should be in a bit less inconvenient format to use. Do you get it from some custom formatter, or does that data looks that way because it is how it is entered in the spreadsheet cells? – ahwayakchih May 31 '16 at 03:06
  • @ahwayakchih Thanks for looking that up for me. The sheet is a simple GET request to https://spreadsheets.google.com/feeds/list/" + spreadsheet + "/od6/public/basic?alt=json`, any ideas? This is through an angular app / trying to avoid having to do OAuth2 as it's a front-end-only site. – JVG May 31 '16 at 04:18
  • If you change `basic` to `full`, you will get additional properties named after values of first row, e.g., "gsx$firstValue" where "$t" will be value of cell. You can also change `list` to `cells` which will give you much more verbose info, describing every cell separately. – ahwayakchih May 31 '16 at 04:56
  • All answers so far try to use simple splitting and assume that ":" nor "," will ever show up in data. I tested adding both characters into cell value, and Google API does not escape them in any way. Cell values are not quoted or anything like that. So there is no simple way to parse it. You'll be safer using `full` format or `cells` view. – ahwayakchih May 31 '16 at 05:01

5 Answers5

5

You can parse it easily with split assuming , and : will never appear in the key or value part.

$t.split(',')
    .map(s => s.split(':'))
    .reduce((o, s) => {
        o[s[0].trim()] = s[1].trim();
        return o;
    }, {});
Bryan Chen
  • 45,816
  • 18
  • 112
  • 143
1

The keys are dynamic but the structure has to remain the same :

{
xxx: "abc",
yyy: "bcd", ...
}

var str = "title: Test Title, gamelabel: Test Game, startdate: 2016-06-14";
var comaSplit = str.split(','), i, arr = [], obj = {};
for (i=0; i < comaSplit.length; i++)
  arr.push(comaSplit[i].split(':'));
for (i=0; i < arr.length; i++)
  obj[arr[i][0]] = arr[i][1];
boehm_s
  • 5,254
  • 4
  • 30
  • 44
1

Take the json from your spreadsheet and break it down and build it back up into an array of objects

var originalData = {
  "somerandomId" : "title: Test Title, gamelabel: Test Game, startdate: 2016-06-14",
  "someotherId" : "title: Test Title2, gamelabel: Test Game2, startdate: 2216-06-14"
};

var finalData = [];

for (var key in originalData) {
  var tmpData = {};

  originalData[key].split(",").forEach(function(item, index){
    var items = item.split(":");
    tmpData[items[0].trim()] = items[1].trim();
  });

  finalData.push(tmpData);
}

console.log(finalData);
JonSG
  • 10,542
  • 2
  • 25
  • 36
1

If you are confident of the structure, then split on colon and comma and use reduce to create the object:

var obj = {$t:'title: Test Title, gamelabel: Test Game, startdate: 2016-06-14'};

console.log(obj.$t.split(/[:,]/).reduce(function(acc, v, i, arr) {
    if (i%2) acc[arr[i-1].trim()] = v.trim();
    return acc;
  },{}));

Or if you're into obfuscated code (not recommended) and ECMAScript 2015 environment (not widely available yet):

var obj = {$t:'title: Test Title, gamelabel: Test Game, startdate: 2016-06-14'};
console.log(obj.$t.split(/[:,]/).reduce((acc,v,i,arr)=>i%2?(acc[arr[i-1].trim()]=v.trim())&&acc:acc,{}));
RobG
  • 142,382
  • 31
  • 172
  • 209
0

Assuming the colon and commas have a pattern, you can use something like:

t = "title: Test Title, gamelabel: Test Game, startdate: 2016-06-14"
var rv = {};
for (var i = 0; i < t.split(/, /).length; ++i){
  rv[t.split(/, /)[i].split(/: /)[0]] = t.split(/, /)[i].split(/: /)[1];
}
console.log(rv)
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268