Using a JavaScript Fetch to get shows. GET works but no data returned

I’d like to be able to programmatically compare our public Spinitron program schedule with schedules in some of our other broadcast software systems to ensure the program schedule is consistent. Can issue a GET which returns OK but without the show data. Sorry, I’m new to using Fetches and still learning JavaScript. My code is below. Am I on the right track? What am I doing wrong? Thanks in advance.

let response = await fetch(‘https://spinitron.com/api/shows’, {

method: 'GET',

headers: {

    'Authorization': 'Bearer ourApiKey',
    'Content-Type': 'application/json',
    'station': 'wfhb',
    'start': '2022-04-02T23:00:00+0000',
    'end': '2022-04-05T02:00:00+0000',
    'fields' :  ['title', 'start', 'duration'] ,

},

});

console.debug(response);

console.debug(response.json());

Hi Chuck, thanks for joining the forum.

Can I issue a GET which returns OK but without the show data? … Am I on the right track?

Maybe.

Would it suit your purposes to be able to ask a question like

  • How many show occurrences are scheduled between {start} and {end}?

And just get a number back, without having to deal with the actual data?

If so, make a HEAD request instead of a GET and look at the x-pagination-total-count response header.

Caution: If you want to work this way, using counts of matching items and ignoring the actual show info in Spinitron, make sure you understand what is and isn’t included in such search results. As the docs say (and correcting my old spelling errors):

itmes can include occurrences that begin or end within the filter range. A show that goes on air before {start} appears in items if it ends after but not at {start}. An occurrence starting at or before {end} is included.

Hi Tom, Thanks for getting back so quickly. I should provide more details . . . both our broadcast automation and our traffic system in development are being fed the program, start, and end/duration for each broadcast in a date range. I want to directly correlate that feed with Spinitron to ensure all systems are in lock step, notifying us if there are any discrepancies. Since the reconciliation process will need to be at regular intervals I’d rather we didn’t have to do the reconciliation by hand.

In that case I would GET the shows as you do in the example code above and then for each of the shows in the response items, check the title, start and end against your other data sources.

Thanks. I’m not parsing the response body properly. Thought I knew what I was doing but now I’m lost. Do you have a response body parse example?

1 Like

Idk about parsing but I can show an example request and response in full.

Here’s a request on WFHB’s actual data looking at one hour on Apr 1 2022 (Friday next week).

$ curl -s -G -i -H 'Authorization: Bearer SECRET' https://spinitron.com/api/shows \
  -d start=2022-04-01T12:00:00Z -d end=2022-04-01T13:00:00Z
HTTP/2 200 
server: nginx
date: Thu, 24 Mar 2022 16:12:51 GMT
content-type: application/json; charset=UTF-8
x-pagination-total-count: 3
x-pagination-page-count: 1
x-pagination-current-page: 1
x-pagination-per-page: 20
link: <https://spinitron.com/api/shows?start=2022-04-01T12%3A00%3A00Z&end=2022-04-01T13%3A00%3A00Z&page=1>; rel=self
set-cookie: _csrf=3a3ba6c7e2473f5fa84140a7e179138908aa8de033410bd0bc7ea6387d18ebbea%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22g3S_CkunW_4XQ77wjSbgMxjTXzcqXFhu%22%3B%7D; path=/; HttpOnly
x-ua-compatible: IE=Edge
x-content-type-options: nosniff
cache-control: no-transform

{"items":[{"id":164985,"start":"2022-04-01T10:00:00+0000","end":"2022-04-01T12:00:00+0000","duration":7200,"timezone":"America/New_York","one_off":false,"category":"Music","title":"Fri Morning Mix 1","description":"","since":null,"url":"","hide_dj":0,"image":"https://farm2.staticflickr.com/1479/23705954504_ceef3fd1e2_m.jpg","_links":{"self":{"href":"https://spinitron.com/api/shows/164985"},"personas":[{"href":"https://spinitron.com/api/personas/126666"},{"href":"https://spinitron.com/api/personas/155984"}],"playlists":{"href":"/api/playlists?show_id=164985"}}},{"id":164868,"start":"2022-04-01T12:00:00+0000","end":"2022-04-01T13:00:00+0000","duration":3600,"timezone":"America/New_York","one_off":false,"category":"News","title":"Democracy Now!","description":"<p>National and international news. Democracy Now! is a national, daily, independent, award-winning news program hosted by journalists Amy Goodman and Juan Gonzalez.</p>","since":null,"url":"http://democracynow.org","hide_dj":1,"image":"https://spinitron.com/images/Show/16/48/164868-img_show-original.png?v=1556555020","_links":{"self":{"href":"https://spinitron.com/api/shows/164868"},"personas":[{"href":"https://spinitron.com/api/personas/126588"}],"playlists":{"href":"/api/playlists?show_id=164868"}}},{"id":164997,"start":"2022-04-01T13:00:00+0000","end":"2022-04-01T15:00:00+0000","duration":7200,"timezone":"America/New_York","one_off":false,"category":"Music","title":"Fri Morning Mix 2","description":"","since":null,"url":"","hide_dj":0,"image":"https://farm5.staticflickr.com/4101/4931771381_4bc4875d58_m.jpg","_links":{"self":{"href":"https://spinitron.com/api/shows/164997"},"personas":[{"href":"https://spinitron.com/api/personas/126855"},{"href":"https://spinitron.com/api/personas/161390"}],"playlists":{"href":"/api/playlists?show_id=164997"}}}],"_links":{"self":{"href":"https://spinitron.com/api/shows?start=2022-04-01T12%3A00%3A00Z&end=2022-04-01T13%3A00%3A00Z&page=1"}},"_meta":{"totalCount":3,"pageCount":1,"currentPage":1,"perPage":20}}

The cURL opts mean

  • -s don’t display the progress thermometer.
  • -G use a GET request and encode -d params into the URL as query params
  • -i display HTTP response headers
  • -H sets a request header
  • -d sets data to be used in a query parameter

Here’s the same thing but without the -i and formatting the JSON response for readability using jq.

$ curl -s -G -H 'Authorization: Bearer SECRET' https://spinitron.com/api/shows \
  -d start=2022-04-01T12:00:00Z -d end=2022-04-01T13:00:00Z | jq .
{
  "items": [
    {
      "id": 164985,
      "start": "2022-04-01T10:00:00+0000",
      "end": "2022-04-01T12:00:00+0000",
      "duration": 7200,
      "timezone": "America/New_York",
      "one_off": false,
      "category": "Music",
      "title": "Fri Morning Mix 1",
      "description": "",
      "since": null,
      "url": "",
      "hide_dj": 0,
      "image": "https://farm2.staticflickr.com/1479/23705954504_ceef3fd1e2_m.jpg",
      "_links": {
        "self": {
          "href": "https://spinitron.com/api/shows/164985"
        },
        "personas": [
          {
            "href": "https://spinitron.com/api/personas/126666"
          },
          {
            "href": "https://spinitron.com/api/personas/155984"
          }
        ],
        "playlists": {
          "href": "/api/playlists?show_id=164985"
        }
      }
    },
    {
      "id": 164868,
      "start": "2022-04-01T12:00:00+0000",
      "end": "2022-04-01T13:00:00+0000",
      "duration": 3600,
      "timezone": "America/New_York",
      "one_off": false,
      "category": "News",
          {
            "href": "https://spinitron.com/api/personas/126588"          }
        ],
        "playlists": {
          "href": "/api/playlists?show_id=164868"
        }
      }
    },
    {
      "id": 164997,
      "start": "2022-04-01T13:00:00+0000",
      "end": "2022-04-01T15:00:00+0000",
      "duration": 7200,
      "timezone": "America/New_York",
      "one_off": false,
      "category": "Music",
      "title": "Fri Morning Mix 2",
      "description": "",
      "since": null,
      "url": "",
      "hide_dj": 0,
      "image": "https://farm5.staticflickr.com/4101/4931771381_4bc4875d58_m.jpg",
      "_links": {
        "self": {
          "href": "https://spinitron.com/api/shows/164997"
        },
        "personas": [
          {
            "href": "https://spinitron.com/api/personas/126855"
          },
          {
            "href": "https://spinitron.com/api/personas/161390"
          }
        ],
        "playlists": {
          "href": "/api/playlists?show_id=164997"
        }
      }
    }
  ],
  "_links": {
    "self": {
      "href": "https://spinitron.com/api/shows?start=2022-04-01T12%3A00%3A00Z&end=2022-04-01T13%3A00%3A00Z&page=1"
    }
  },
  "_meta": {
    "totalCount": 3,
    "pageCount": 1,
    "currentPage": 1,
    "perPage": 20
  }
}

There are also some simple examples in the api docs.

Does this help?

Thanks, that’s so nice of you! Since you’re the voice of Spinitron videos and the forum moderator I’m guessing the Spinitron operations is pretty lean. Taking the time to help me out with examples in that environment is even more appreciated.

Your curl example works just fine for me. I’m using JavaScript though, and my current problem is in how I’m encoding the parameters for the GET into the URL. I’m homing in on my bug.

As an IT guy, I really like how Spinitron’s architecture partitions the whole spins, shows, and web page problem space. As a DJ, I’m also very grateful I don’t need to enter spin data any more :blush:

Thanks!

Thanks for your kind comments.

As far as your JavaScript goes, you can paste what you’ve got and we can all chip in at tell you everything we can think of that’s wrong with it… you know. The Internet.

I got it working. Did some research because I felt the learning exercise would be worth it :slight_smile: This is in-line code but I’ll wrap it in a function and ensure that it isn’t always hitting the server for the data. Here’s what worked:

const params = {

    "start" : "2022-04-01T12:00:00Z",

    "end" : "2022-04-01T23:59:59Z",

    'fields' :  ['title', 'start', 'duration'] 

};

let url = "https://spinitron.com/api/shows";

url += '?' + new URLSearchParams(params).toString();

console.debug("url:" + url);

let response = await fetch(url, {

    method: 'GET',

    headers: {

        'Authorization': 'Bearer secret',

        'Content-Type': 'application/json',

    },

});


console.debug(response.body);
1 Like

Great.

You don’t need the line that sets params.fields since that query parameter will be ignored by the server.

Apart from that it looks like it should work.

Huh. When I leave the params.fields in, I get back just the three items I ask for (Title, Start, Duration). When I remove it, I get back all fields. Honest!

1 Like

omg, that’s amazing.

ftr, in the cURL commands i showed above, you just add -d 'fields=title,start,duration'