Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React/Redux + Soundcloud API

UPDATE

See the working example here: Favesound-Redux

Live: http://www.favesound.de/

Tutorial: http://www.robinwieruch.de/the-soundcloud-client-in-react-redux

Question

Recently I discovered and got inspired by Sound Redux which shows how to use the Soundcloud API within a React + Redux app. The Soundcloud API requires you to setup a callback.html page. The Sound Redux app solves this by serving the callback.html from a Go Lang Server. I don't want to use any server side technology for this. Thats why I was wondering if it is possible to serve the callback.html as a react component. My setup already pops up the authentication modal for Soundcloud, but after entering my credentials nothing happens and the modal gets blank.

In my root component I setup the route for the Callback component and my app component.

const routes = <Route component={App}>
  <Route path="/callback" component={Callback} />
  <Route path="/app" component={SoundContainer} />
</Route>;

ReactDOM.render(
  <Provider store={store}>
     <Router>{routes}</Router>
  </Provider>,
  document.getElementById('app')
);

When I fire the authentication request action from within my SoundContainer, the action creator looks like the following:

export function auth() {
  return dispatch => {
    SC.initialize({
      client_id: MY_CLIENT_ID,
      redirect_uri:`${window.location.protocol}//${window.location.host}/#/callback`
    });

    SC.connect(function (response) {
      console.log('connect'); // This does not appear in the console
      SC.get('/me', function(data) {
        console.log(data);
        dispatch(doAuth(data));
      })
    });
  }
}

Like I said, after entering my credentials in the modal the modal gets blank and nothing happens.

When I output ${window.location.protocol}//${window.location.host}/#/callback it is the same as my Redirect Uri in my Soundcloud Account: http://localhost:8080/#/callback

My Callback component looks like this:

export default React.createClass({
  render: function() {
    return <html>
      <head>
        <title>Callback</title>
      </head>
      <body onload="window.setTimeout(opener.SC.connectCallback, 1);">
        <p>
          This page should close soon
        </p>
      </body>
    </html>
  }
});
like image 505
Robin Wieruch Avatar asked Dec 26 '15 18:12

Robin Wieruch


2 Answers

Firstly, neat idea.

As your are using hashes, the callback would only be a fragment, not a complete page. The callback code shouldn't have <html> in it. Could you try this instead?

export default React.createClass({
  componentDidMount:function(){
    window.setTimeout(opener.SC.connectCallback, 1);
  },
  render: function() {
    return (
      <div>
          <p>
            This page should close soon
          </p>
      </div>
    );
  }
});

UPDATES

OK, so oAuth2 doesn't like fragments in return callback urls, probably that's why the code isn't working. However you can have your express server serve the spa back on the callback route. This technique is documented in detail in react-router createBrowserHistory docs. So the callback URL will serve your spa page and the login will complete.

like image 51
hazardous Avatar answered Oct 03 '22 00:10

hazardous


Yeah, I initially tried to do the same thing. I'm fairly certain that it has to do with the hash. Perhaps it has to do with the source and callback page being essentially the same url (if you ignore hashes). After tearing my hair out for a good hour or so, trying to get it to work, i just gave up and served /callback on the server side :)

like image 23
Andrew Nguyen Avatar answered Oct 03 '22 00:10

Andrew Nguyen