Yaron Christiaens
Yaron Christiaens

Reputation: 11

Display SectionList from API data in react native

I'm trying to create a SectionList from data received from an API. This API has the following structure for the ingredients that I want to display:

const ingredients = {
    malt: [
      {
        name: 'Maris Otter Extra Pale',
        amount: {
          value: 3.3,
          unit: 'kilograms',
        },
      },
      {
        name: 'Caramalt',
        amount: {
          value: 0.2,
          unit: 'kilograms',
        },
      },
      {
        name: 'Munich',
        amount: {
          value: 0.4,
          unit: 'kilograms',
        },
      },
    ],
    hops: [
      {
        name: 'Fuggles',
        amount: {
          value: 25,
          unit: 'grams',
        },
        add: 'start',
        attribute: 'bitter',
      },
      {
        name: 'First Gold',
        amount: {
          value: 25,
          unit: 'grams',
        },
        add: 'start',
        attribute: 'bitter',
      },
      {
        name: 'Fuggles',
        amount: {
          value: 37.5,
          unit: 'grams',
        },
        add: 'middle',
        attribute: 'flavour',
      },
      {
        name: 'First Gold',
        amount: {
          value: 37.5,
          unit: 'grams',
        },
        add: 'middle',
        attribute: 'flavour',
      },
      {
        name: 'Cascade',
        amount: {
          value: 37.5,
          unit: 'grams',
        },
        add: 'end',
        attribute: 'flavour',
      },
    ],
    yeast: 'Wyeast 1056 - American Ale™',
  };

The desired result is the following using SectionList (with malt and hops as section headers):

Visual example of result

I've already tried to use functions like Object.values(), with no result at all. The code simply looks like the following, receiving the beer from the previous view(with a beer list):

const Detail = ({ route }) => {
  const beer = route.params.beer;
  const ingredientsFormatted = Object.values(beer.ingredients);
  return(
  <SectionList
    sections={ingredientsFormatted}
    renderItem={({ item }) => {
          <Text>{item.name}</Text>; //Here there has to be the name of the different ingredients
        }}
        renderSectionHeader={({ section }) => <Text>{section}</Text>} //Here there has to be malt, hops or yeast
        keyExtractor={(item) => item.name}
      ></SectionList>
)}

Upvotes: 1

Views: 455

Answers (1)

kiuQ
kiuQ

Reputation: 1196

There are 2 problems in your ingredients data.

  1. Format in value for yeast is not the same as the others.
  2. Your data inserted into SectionList is not the format recommended by React-Native Offical docs.

To fix this, you can modify your API return / map the data after retrieved from server.

const Detail = ({ route }) => {
  const beer = route.params.beer;
  let sectionListTemplate = [];

  for (let [key, value] of Object.entries(beer.ingredients)) {
    //console.log(`${key}: ${JSON.stringify(value)}`);

    if(!Array.isArray(value)){
      //Handle case for 'yeast' which its data is not an array
      sectionListTemplate.push({
        title: key,
        data: [{
          name: value
        }]
      })
    }
    else{
      //Map value for general cases
      sectionListTemplate.push({
        title: key,
        data: value
      })
    }
  }

  return(
    <SectionList
      sections={sectionListTemplate}
      renderSectionHeader={({ section }) => {
        return(
          //Here there has to be malt, hops or yeast
          <Text style={{fontWeight: 'bold'}}> 
            {section.title}
          </Text>
        )
      }} 
      renderItem={({ item }) => {
        return(
          //Here there has to be the name of the different ingredients
          <Text>
            {item.name}
          </Text> 
        )
      }}
      keyExtractor={(item) => item.name}
    >
    </SectionList>
  )
)}

Upvotes: 0

Related Questions