0

I am breaking down a larger post into smaller questions. Please understand I never used Promise before and that I am new to React-Native too. It would be great to get feedback and recommendations on how to setup API calls and handle the data.

How can I dynamically create URLs for API requests? Here's what I am trying to achieve:

Pseudocode

Child

  • Retrieve two variables
  • Use these two variables to build an URL
  • Trigger the first Promise and resolve
  • Retrieve another two variables
  • Use these two variables to build a new an URL
  • Trigger the second Promise and resolve
  • Gather the data from both promises and pass to parent

Parent

  • Retrieve data from Child
  • Get data from the first Promise and set to a state
  • Get data from the second Promise and set to another state

APIservice.js

Child

class APIservice {


    _getStopPoint = (endpoint) => {
        return new Promise(function(resolve, reject) {
            fetch(endpoint)
            .then((response) => response.json())
            .then((data) => {
                console.log("APIservice StopPoint", data)
                resolve(data);
            });
        });
    };
};


module.exports = new APIservice

List.js

Parent

As you can see, the way I setup the endpoint is lame. It's not ideal as the URL is the same. I want to structure something that can receive two variables and build the URL on the go. Something like https://api.tfl.gov.uk/Line/${routeid}/Arrivals/${stationid}.

If I manage that, how can I pass the API call to the APIservice having only one endpoint that dynamically will change based on the two variables it receives? I am not sure how to differentiate the call in the Promise.all having only "one" URL.

let APIservice = require('./APIservice')

let endpoint = 'https://api.tfl.gov.uk/Line/55/Arrivals/490004936E'
let endpoint1 = 'https://api.tfl.gov.uk/Line/Northern/Arrivals/940GZZLUODS'

export class List extends Component {
    constructor(props) {
        super(props);

        this.state = {
            bus: null,
            tube: null,
        }
    };

    componentWillMount() {
        let loadData = (endPoint) => {

            Promise.all([
                APIservice._getStopPoint(endpoint),
                APIservice._getStopPoint(endpoint1),
            ])
            .then((data) => {

                // Name for better identification
                const listBus = data[0]
                const listTube = data[1]

                this.setState({
                    bus: listBus,
                    tube: listTube
                }, () => {
                    console.log("bus", this.state.bus, "tube", this.state.tube)
                });
            })
            .catch((error) => {
                console.log(error)
            })
        }

        loadData(endpoint);
        loadData(endpoint1);

    }

    render() {
        return(
            <View>
                <FlatList 
                data={this.state.bus}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
                <FlatList 
                data={this.state.tube}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
            </ View>
        );
    }
};

1 Answer 1

1

It is pretty easy to implement what you are saying once you understand how this works.

You are using fetch for your API calls which returns a Promise upon use. The pseudo-code for your use case would be something like this:

class APIService {
    static fetchFirst(cb) {
        fetch('FIRST_URL')
            .then(resp => {
                try {
                    resp = JSON.parse(resp._bodyText);
                    cb(resp);
                } catch(e) {
                    cb(e);
                }
            })
            .catch(e => cb(e));
    }

    static fetchSecond(routeid, stationid, cb) {
        fetch(`https://api.tfl.gov.uk/Line/${routeid}/Arrivals/${stationid}`)
            .then(resp => {
                try {
                    resp = JSON.parse(resp._bodyText);
                    cb(resp);
                } catch(e) {
                    cb(e);
                }
            })
            .catch(e => cb(e));
    }
}

module.exports = APIService;

Include this in your parent component and use it as follows:

let APIService = require('./APIService')

export class List extends Component {
    constructor(props) {
        super(props);

        this.state = {
            bus: null,
            tube: null,
        }
    };

    componentWillMount() {
        APIService.fetchFirst((resp1) => {
            APIService.fetchSecond(resp1.routeid, resp1.stationid, (resp2) => {
                this.setState({
                    tube: resp2
                });
            });
        });
    }

    render() {
        return(
            <View>
                <FlatList 
                data={this.state.bus}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
                <FlatList 
                data={this.state.tube}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
            </ View>
        );
    }
};

I haven't checked the errors on the callback function, please see that the errors are handled when you use this.

Sign up to request clarification or add additional context in comments.

12 Comments

Ow... BOOM. Okay, I will need to analyse line by line and try to understand what's going on. Regardless, thank you for the reply!
@DiegoOriani Sure! Let me know if you don't understand any piece. I'd love to explain it to a fellow newbie :)
Okay, let's start easy. What static does? I can't find it in the documentation.
@DiegoOriani static is a "visibility modifier" in JS. You can look it up anywhere for ex. here
Cool, I will try some stuff here. I really appreciate the help.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.