Harry
Harry

Reputation: 1091

How to fetch data from multiple urls and save it in an array (react native)

I have an array of RSS URLs that i would like to get data from and save that data in one array. here is my code:

// rss urls array
var URLS = [
  "https://www.wired.com/feed/rss",
  "http://feeds.bbci.co.uk/news/rss.xml",
  "http://www.nasa.gov/rss/dyn/breaking_news.rss"
];

I have a data variable in my state where i would like the data to get stored

constructor() {
    super()
    this.state = {
      data: []
    }
  }

I use the fetchData() function to attempt to fetch the Data

  fetchData() {
    var urlArray = [];

    for (var i = 0; i < URLS.length; i++) {
      urlArray.push(URLS[i]);
    }

    fetch(urlArray)
      .then((response) => response.text())
      .then((responseData) => {
        this.setState({
          data: this.extractData(responseData)
        });
      }).done();
  }


  componentDidMount() {
    this.fetchData();
  }

I use the extractData function to get data from the rss feed like this

  extractData(text) {
    var doc = new DOMParser().parseFromString(text, 'text/xml');
    var items_array = [];
    var items = doc.getElementsByTagName('item');

    for (var i = 0; i < items.length; i++) {
      items_array.push({
        title: items[i].getElementsByTagName('title')[0].lastChild.data,
        description: items[i].getElementsByTagName('description')[0].lastChild.data,
        //thumbnail: items[i].getElementsByTagName('enclosure')[0].getAttribute('url'),
        //link: items[i].getElementsByTagName('link')[0].textContent,
        //date: items[i].getElementsByTagName('pubDate')[0].textContent,                    
      })
    }
    return items_array;
  }

But when i run i am getting an error saying "cannot load an empty URL"

Upvotes: 1

Views: 2314

Answers (2)

Peter Lazar
Peter Lazar

Reputation: 71

In addition to @guest271314 answer, modify the setState call as

this.setState((prevState, props) => ({ data: [...prevState.data, this.extractData(responseData)] })

In your earlier code you were overwriting the data array every time a request completed. In the above snippet, you can see that it's adding the new response to the previous array.

Upvotes: 1

guest271314
guest271314

Reputation: 1

You are passing an array to fetch() instead of a string or Request object. You can use Promise all or async/await and a loop to make multiple calls to fetch() and get result when all requests complete or log error if any other the requests throw an error. You can also handle the error and continue the loop to get both successful requests and error messages.

  fetchData() {    
    return Promise.all(
      URLS.map(url => 
        fetch(url)
        .then(response => response.text())
        .then(responseData => {
          this.setState({
            data: this.extractData(responseData)
          })
        })
        .catch(err => /* handle errors here */ console.error(err))
      )
    ).then(() => {// do stuff}, err => {// handle error})
  }

It is not clear from Question what .done() is or what the expected result of calling .done() is.

Upvotes: 3

Related Questions