jsoma/tabletop — pull request #48 by ghing (2014-04-26 23:19:40+00:00)
Title: Fix determination of worksheet ID for new sheets

Tabletop.loadSheets uses this logic to determine each worksheet's ID from the worksheets feed (https://spreadsheets.google.com/feeds/worksheets/{{SPREADSHEET_KEY}}/public/basic?alt=json):

```
var sheet_id = data.feed.entry[i].link[3].href.substr( data.feed.entry[i].link[3].href.length - 3, 3);
```

For old sheets, ``data.feed.entry.links`` has 4 entries:

```
link: [
{
rel: "http://schemas.google.com/spreadsheets/2006#listfeed",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/feeds/list/{{SPREADSHEET_KEY}}/od6/public/basic"
},
{
rel: "http://schemas.google.com/spreadsheets/2006#cellsfeed",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/feeds/cells/{{SPREADSHEET_KEY}}/od6/public/basic"
},
{
rel: "http://schemas.google.com/visualization/2008#visualizationApi",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/tq?key={{SPREADSHEET_KEY}}&sheet=od6&pub=1"
},
{
rel: "self",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/feeds/worksheets/{{SPREADSHEET_KEY}}/public/basic/od6"
}
]
```

and the code correctly extracts ``od6`` from the ``href`` property of the last ``link`` element.

For new sheets, however, ``data.feed.entry.links`` has 5 entries:

```
link: [
{
rel: "http://schemas.google.com/spreadsheets/2006#listfeed",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/feeds/list/{{SPREADSHEET_KEY}}/od6/public/basic"
},
{
rel: "http://schemas.google.com/spreadsheets/2006#cellsfeed",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/feeds/cells/{{SPREADSHEET_KEY}}/od6/public/basic"
},
{
rel: "http://schemas.google.com/visualization/2008#visualizationApi",
type: "application/atom+xml",
href: "https://docs.google.com/spreadsheets/d/{{SPREADSHEET_KEY}}/gviz/tq?gid=0&pub=1"
},
{
rel: "http://schemas.google.com/spreadsheets/2006#exportcsv",
type: "text/csv",
href: "https://docs.google.com/spreadsheets/d/{{SPREADSHEET_KEY}}/export?gid=0&format=csv"
},
{
rel: "self",
type: "application/atom+xml",
href: "https://spreadsheets.google.com/feeds/worksheets/{{SPREADSHEET_KEY}}/public/basic/od6"
}
]
```

So, the code will incorrectly grab ``csv`` from the end of the fourth link element, instead of ``od6`` from the end of the last link element.

While this method of extracting the worksheet ID seems to be too brittle in general and might be worth reconsidering, we can make the existing method work for both old and new sheets by inspecting the last link element instead of the fourth:

```
var linkIdx = data.feed.entry[i].link.length-1;
var sheet_id = data.feed.entry[i].link[linkIdx].href.substr( data.feed.entry[i].link[linkIdx].href.length - 3, 3);
```

Without this fix, we get the error "Cannot read property 'title' of undefined" in Tabletop.Model as a result of no data being retrieved from an incorrectly constructed sheet list feed URL (https://spreadsheets.google.com/feeds/list/{{SPREADSHEET_KEY}}/csv/public/values?alt=json).

Note that this pull request also contains the change for https://github.com/jsoma/tabletop/pull/46