codinginnewyork
codinginnewyork

Reputation: 1128

Nested API calls in React.js

I'm creating a web app in React that needs to handle 2 API calls where one is dependent on the other. The first API call will grab data from OpenWeather API - and then the 2nd API call will use that callback data to make a call to Spotify's API.

How can I set up this nested/dependent API call in React? Can I run an ajax call under the success function of the first API call? Or do I need to create a new component that handles the 2nd API, that will somehow get the data from the first API call?

    // Making the API call to OpenWeather API:
var CityInfo = React.createClass({
    getInitialState: function() {
        return {data: {}};
    },
    loadCityInfo: function(e){
    var city = $(e.currentTarget).data('city');
        $.ajax({
            url: 'http://api.openweathermap.org/data/2.5/weather?q='+city,
            method: 'GET',
            success: function(result) {
                this.setState({data: result});
                console.log(result);

            }.bind(this)
        });
    },
    render: function() {
        return (
            <div>
                <h2><button onClick={this.loadCityInfo} data-city={this.props.info.name}>{this.props.info.name}</button></h2>
            </div>
        );
    }
});

Full code: https://jsbin.com/lefupo/edit?js,output

Upvotes: 2

Views: 5184

Answers (2)

Felix Kling
Felix Kling

Reputation: 816462

Can I run an ajax call under the success function of the first API call?

Of course. The success function is just another function. You can execute any other JavaScript in it.

However, it would be cleaner to utilize the fact the $.ajax returns a promise. So you could write this instead:

getWeatherData(city) // contains the Ajax call to OpenWeather
.then(getSpotifyData) // contains call to Spotify, gets passed result from getWeatherData
.then(function(result) {
  // update state
});

See Deferreds for more info.

Upvotes: 1

John Ruddell
John Ruddell

Reputation: 25842

I would recommend you follow flux pattern for making your requests especially.. however with what you have you can make a chained request

var CityInfo = React.createClass({
    loadCityInfo: function(e){
        var city = $(e.currentTarget).data('city');
        $.ajax({
            url: 'http://api.openweathermap.org/data/2.5/weather?q='+city+"&APPID=3c8e84ea9c6f7938384d3c3980033d80",
            method: 'GET',
            success: function(result) {
                this.setState({data: result});
                console.log(result);
                // make request here
            }.bind(this)
        });
    }
});

now that aside the way you can do this with flux pattern is have an actions file that does the requests..

module.exports = {
    loadWeather: function(city){
        return $.ajax({
            url: 'http://api.openweathermap.org/data/2.5/weather?q='+city+"&APPID=3c8e84ea9c6f7938384d3c3980033d80",
            method: 'GET'
        });
    },
    loadSpotify: function(params){
        //do request here
    }
}

then in your loadcity function you can just do this

loadCityInfo: function(e){
    var city = $(e.currentTarget).data('city');
    actions.loadWeather(city).done(function(res){
        //set your state
        actions.loadSpotify(params)
    }).fail(funciton(res){
        //handle fail
    });
}

Upvotes: 1

Related Questions