Tutorials: Station Playback

Retrieving a current source

The query is added to the currentlyPlaying.graphql file under src > graphql > queries.

#import "../fragments/trackItem.graphql"
#import "../fragments/audioAdItem.graphql"
#import "../fragments/artistMessageItem.graphql"
#import "../fragments/customTrackItem.graphql"
#import "../fragments/idleTimeoutItem.graphql"
#import "../fragments/simStreamViolationItem.graphql"
#import "../fragments/voiceTrackItem.graphql"

query currentPlaying($deviceUuid: String!) {
 playback {
   current (deviceUuid: $deviceUuid) {

Fragments are used for the different playback source types, since these are reused in other queries and mutations.  To get a better understanding of the different types and when they would be used, head over to this section.

The deviceUuid is sent to the query to fetch the last active source on a specific device.  When you change the deviceUuid you will get a different source or an error to say that a source has not been set.

A provider was created that serves 2 main functions:

  1. Export the query in order for components to use the query as is
  2. Export a higher-order component that takes a Component and returns the component with 3 properties (isLoading, playbackItem, and errorMessage) set once the query is run. 

These exports can be found in this file: src > graphql > playback > currentlyPlaying.jsx.

const currentlyPlaying = loader('../queries/currentlyPlaying.graphql');

const withCurrentlyPlaying = graphql(currentlyPlaying, {
 skip: (props) => !props.deviceUuid,
 props: ({ ownProps, data: { loading, playback, error } }) => {
   let errorMessage = error && error.message !== ErrorType.SOURCE_NOT_SET && 'Something went wrong';
   if (errorMessage === ErrorType.SKIP_LIMIT_REACHED) {
     errorMessage = 'Skip limit reached';

   let playbackItem = undefined;
   if (playback) {
     let { current } = playback;
     let { audioUrl, feedbackValue, index, interactions, track, sourceId, trackToken } = current ? current : {};
     let { meta } = track ? track : {};
     let { art, artist, duration, name: trackTitle, id: trackId } = meta ? meta : {};
     let { url } = art ? art : {};
     let { name: artistName } = artist ? artist : {};

     playbackItem = {

   let playbackProps = {
     isLoading: loading,
     errorMessage: errorMessage,
   return playbackProps;
 options: ({ deviceUuid }) => {
   return { variables: { deviceUuid } }}

 export { withCurrentlyPlaying, currentlyPlaying };

In the above code example you will see that the query is imported and loaded with the graphql.macro library.  This library compiles GraphQL ASTs at build time using babel macros.

The provider (withCurrentlyPlaying) is then created.  It takes a component as an argument and returns a new component with 3 properties:  

The response of the query is transformed into a flatter structure that is easier to use in components using this provider.

The provider and the query is then both exported.