L.U.
L.U.

Reputation: 521

Return and render looped text items from XML on React Native in a list

I've found a way to extract items from an XML within ComponentDidMount method and loop them. I also managed to pass them on to the 'render' section of Component and return them as one big wall of strings, but I will need to display them as a list so that one line will be dedicated to one item.

This is my current demo: https://snack.expo.io/@leourushi/api-looping-00

This is the original XML I’m pulling data from: https://www.wmata.com/rider_tools/metro_service_status/feeds/mis/rail.xml

And I used this tool to parse XML into readable format: https://www.npmjs.com/package/react-native-rss-parser

I’m trying to create a list view similar to this one: https://www.wmata.com/service/status/#lines-affected

I used map function to extract short titles of travel alerts (Yellow Line, Blue Line etc) and more detailed description texts. I stored them into variables named them gimmeNames and gimmeDescriptions respectively.

Now I would like to display them side by side in a list view.

I created empty state names at the top as below:

    constructor(props) {
        super(props);
        this.state = {
            rss: [],
            gimmeNames: "",
            gimmeDescriptions: ""
        };
    }

Within componentDidMount, I defined the original URL, ran a ‘fetch’ operation and created two loop functions. And I defined the results as gimmeNames and gimmeDescriptions.

    componentDidMount() {
var url = 'https://www.wmata.com/rider_tools/metro_service_status/feeds/mis/rail.xml';

    return fetch(url)
  .then((response) => response.text())
  .then((responseData) => rssParser.parse(responseData))
  .then((rss) => {
    const gimmeNames = rss.items.map(function(item, index) {
      return (item.title);
    });
    const gimmeDescriptions = rss.items.map(function(item, index) {
      return (item.description);
    });

this.setState({
  gimmeNames: gimmeNames,
  gimmeDescriptions: gimmeDescriptions,
  rss: rss
});

  });

}

Here is my attempt to render them side by side. But currently I have one big chunk of ALL the looped title names and another chunk of ALL the description items.

    render() {

  const { rss, gimmeNames, gimmeDescriptions } = this.state;

  return(

<View style={styles.bigContainer}>
<View style={styles.box}>

<Text> Title: Hard coded strings for now </Text>
<View style={styles.lineItem}>
<View style={styles.lineRow}>


<Text style={styles.leftColumn}>{gimmeNames}</Text>
<Text style={styles.rightColumn}>{gimmeDescriptions}</Text>

</View>
</View>
</View>
</View>

    )
}

I am definitely doing this wrong. But I don't know how to get to the right answer. Any pointer would be appreciated.

Upvotes: 0

Views: 481

Answers (1)

Charlotte_Anne
Charlotte_Anne

Reputation: 382

I think this will work. It's similar to other examples that have worked for me before:

constructor(props) {
    super(props);
    this.state = {
        rss: []
    };
}

And then when you fetch the data:

componentDidMount() {
var url = 
'https://www.wmata.com/rider_tools/metro_service_status/feeds/mis/rail.xml';

return fetch(url)
.then((response) => response.text())
.then((responseData) => rssParser.parse(responseData))
.then((rss) => {
 console.log(rss)
 this.setState({
 rss: rss
 });

 });

 }

And then when you render them:

render() {


  const gimmeItems = this.state.rss.items.map((item) =>

   <View style={styles.lineItem}>
   <View style={styles.lineRow}>


     <Text style={styles.leftColumn}>{item.title}</Text>
     <Text style={styles.rightColumn}>{item.description}</Text>

  </View>
  </View>

);


return(

<View style={styles.bigContainer}>
<View style={styles.box}>

 <Text> Title: Hard coded strings for now </Text>
 {gimmeItems}
</View>
</View>

)
}

Upvotes: 1

Related Questions