2

I'm currently trying to iterate through a json in react native. The JSON has a variable number of returns that are formatted very strangely, Unfortunately I can't do much to change how the JSON is created, so I'm hoping to get advice on how to parse it correctly.

Here's the code that should fetch() the json and display the values:

import React, { useState, useEffect } from "react";
import { ActivityIndicator, FlatList, SafeAreaView, StatusBar, StyleSheet, Text, View, TouchableOpacity } from "react-native";

const App = () => {
  const [selectedId, setSelectedId] = useState(null);
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState({});
  const [counter, setCounter] = useState(0);

  const getJSON = async () => {
    const response = await fetch('URL');
    const json = await response.json();
    setData(json.Items);
    setCounter(json.Count);
    setLoading(false);
  }

  useEffect(() =>{
    getJSON();
  }, []);

  return (
    <View style={{ flex: 1, padding: 24 }}>
    {isLoading ? <ActivityIndicator/> : (
      <FlatList
        data={data}
        keyExtractor={({ Items }, index) => id}
        renderItem={({ item }) => (
          <Text>{item.Items}</Text>
        )}
      />
    )}
  </View>
  );
};

And here's the JSON that is fetched():

{
    "Count": 1,
    "Items": [{
        "building": {
            "S": "Wash"
        },
        "mac": {
            "S": "FF:FF:FF:FF:FF:FF"
        },
        "name": {
            "S": "test asset"
        },
        "asset_id": {
            "S": "01"
        },
        "floor": {
            "S": "1"
        },
        "room": {
            "S": "102"
        }
    }],
    "ScannedCount": 1
}

Any help would be appreciated. I'm still quite new to parsing JSONS

1 Answer 1

1

I suggest pre-processing the Items response value into a more usable format to be rendered. You'll want to "unpack" the nested S property of each nested outer key. You can then map/access the item element properties more easily.

Example:

const { Items } = {
  Count: 1,
  Items: [
    {
      building: { S: "Wash" },
      mac: { S: "FF:FF:FF:FF:FF:FF" },
      name: { S: "test asset" },
      asset_id: { S: "01" },
      floor: { S: "1" },
      room: { S: "102" }
    },
  ],
  ScannedCount: 1
};

const data = Items.map((obj) =>
  Object.entries(obj).reduce((items, item) => {
    const [key, { S: value }] = item;
    return {
      ...items,
      [key]: value
    };
  }, {})
);

console.log(data);

Code:

function App() {
  const [selectedId, setSelectedId] = useState(null);
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [counter, setCounter] = useState(0);

  const getJSON = async () => {
    const response = await fetch("URL");
    const json = await response.json();
    const { Count, Items } = json;

    const data = Items.map((obj) =>
      Object.entries(obj).reduce((items, item) => {
        const [key, { S: value }] = item;
        return {
          ...items,
          [key]: value
        };
      }, {})
    );

    setData(data);
    setCounter(Count);
    setLoading(false);
  };

  useEffect(() => {
    getJSON();
  }, []);

  return (
    <div className="App">
      {isLoading ? (
        <h2>Loading...</h2>
      ) : (
        <FlatList
          data={data}
          keyExtractor={({ asset_id }) => asset_id}
          renderItem={({ item }) => (
            <View key={item.asset_id}>
              <Text>
                Location: {item.building} {item.floor}-{item.room}
              </Text>
              <Text>Name: {item.name}</Text>
              <Text>MAC: {item.mac}</Text>
              <Text>Asset Id: {item.asset_id}</Text>
            </View>
          )}
        />
      )}
    </div>
  );
}

Edit json-fetch-parsing-issues-in-react-native

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

2 Comments

Fantastic answer! You've really made my weekend, thank you. Strangely enough, your code works on the sandbox but not in my development environment. Easy fix though, just had to replace the outer <div> with <View> and it worked. I probably imported something incorrectly. Thanks again!
@Teekink Yeah, that's because codesandbox was vanilla React code instead of React-Native code. I tried to use the RN components in the code example above. Sorry for any confusion that may've caused. Cheers and good luck!

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.