-1

I am using SWR to complete a simple API request however after I just finished formatting the API how I wanted SWR is now stuck In it's loading state and I am very confused as to why I have tried a few different things and none have yet to resolve my issue.

I know the response from the API includes a JSON object and in the code I did try to convert to a JavaScript object however it seems to not help.

In the fetcher I have set it to return the data and dig into the JSON object, If I remove British_Roles from the return then Next.js will return an error saying the map is not a function.

Have a feeling it could be a simple issue I am missing, but please keep in mind I am no pro. Any help would be greatly accepted

import {
  Table,
  TableCaption,
  Thead,
  Tr,
  Th,
  Tbody,
  Td,
  Tfoot,
  Text,
  Accordion,
  AccordionItem,
  AccordionButton,
  AccordionPanel,
  AccordionIcon,
  Box,
  Center,
  Stack,
  Heading,
  VStack,
} from "@chakra-ui/react";
import useSWR from "swr";
import axios from "axios";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

const fetcher = async (url, key) => {
  const res = await axios.get(url, {
    headers: {
      Authorization: `Bearer ${key}`,
      "Content-Type": "application/json",
    },
  });
  return res.data.data.attributes;
};

export const InsurgentDropdown = () => {
  var key = process.env.REACT_APP_API_KEY;
  var key =
    "xxx";
  const { data, error } = useSWR(
    ["https://api.squadkitresearch.net/api/britishes/1?populate=%2A", key],
    fetcher
  );

  if (error)
    return console.log(error), (<div>Failed to load {error.message}</div>);
  if (!data) return <div>Loading...</div>;

// using roles or data in the map below makes no difference
  return (
    <>
        {data.map((faction) => (
          <VStack p="5">
            <Accordion allowToggle>
              <AccordionItem>
                <AccordionButton>
                  <Box flex="1" textAlign="left">
                    <Heading fontSize="20px">
                      {faction.role_name || "Data Error"}
                    </Heading>
                  </Box>
                  <AccordionIcon />
                </AccordionButton>
                <AccordionPanel>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
                  do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                  Ut enim ad minim veniam, quis nostrud exercitation ullamco
                  laboris nisi ut aliquip ex ea commodo consequat.
                </AccordionPanel>
              </AccordionItem>
            </Accordion>
            <Accordion allowToggle>
              <AccordionItem>
                <h2>
                  <AccordionButton>
                    <Box flex="1" textAlign="left">
                      <Heading fontSize="20px">
                        {faction.role_name || "Data Error"}
                      </Heading>
                    </Box>
                    <AccordionIcon />
                  </AccordionButton>
                </h2>
                <AccordionPanel pb={4}>
                  <Table variant="striped" colorScheme="teal">
                    <TableCaption fontSize="15px">
                      {faction.role_name || "Squad Kit Weapon Name"} Role
                      Information
                    </TableCaption>
                    <Thead>
                      <Tr>
                        <Th fontSize="20px">Primary Weapon</Th>
                        <Th fontSize="20px">Magazine Size</Th>
                        <Th fontSize="20px">Weapon Sights Type</Th>
                        <Th fontSize="20px">Weapon Firing Modes</Th>
                        <Th isNumeric fontSize="20px">
                          Magazine Count
                        </Th>
                      </Tr>
                    </Thead>
                    <Tbody>
                      <Tr>
                        <Td>{faction.Primary || "Data Error"}</Td>
                        <Td>
                          {faction.Primary_Magazine_Round_Amount ||
                            "Data Error"}
                        </Td>
                        <Td>{faction.Primary_Sights || "Data Error"}</Td>
                        <Td>{faction.Primary_Firing_Modes || "Data Error"}</Td>
                        <Td>
                          {faction.Primary_Magazine_Amount || "Data Error"}
                        </Td>
                      </Tr>
                    </Tbody>
                    <Tr>
                      <Th fontSize="20px">Secondary Weapon</Th>
                      <Th fontSize="20px">Magazine Size</Th>
                      <Th fontSize="20px">Weapon Sights Type</Th>
                      <Th fontSize="20px">Weapon Firing Modes</Th>
                      <Th isNumeric fontSize="20px">
                        Magazine Count
                      </Th>
                    </Tr>
                  </Table>
                </AccordionPanel>
              </AccordionItem>
            </Accordion>
          </VStack>
        ))}
    </>
  );
};

// API Response

{
    "data": {
        "id": 1,
        "attributes": {
            "Role_Name": "British Squad Lead (Iron Sights)",
            "createdAt": "2022-02-05T05:55:35.926Z",
            "updatedAt": "2022-02-05T05:55:38.194Z",
            "publishedAt": "2022-02-05T05:55:38.184Z",
            "locale": "en",
            "British_Roles": [
                {
                    "id": 1,
                    "role_name": "British Squad Lead (Iron Sights)",
                    "Primary": "L85A2 + Foregrip + Bipod",
                    "Primary_Sights": "Iron Sights",
                    "Primary_Firing_Modes": "Auto/Single",
                    "Primary_Magazine_Amount": 7,
                    "Primary_Magazine_Round_Amount": 30,
                    "Secondary": "L131A1",
                    "Secondary_Sights": "Iron Sights",
                    "Secondary_Firing_Modes": "Single",
                    "Secondary_Magazine_Amount": 2,
                    "Secondary_Magazine_Round_Amount": null,
                    "Secondary_Knife": "SA80 Bayonet"
                }
            ],
            "British_Role_Extras": [
                {
                    "id": 1,
                    "__component": "loadouts.third-slot",
                    "Third_Slot_Item": "L109A1 Fragmentation Grenade",
                    "Item_Amount": 2
                },
                {
                    "id": 1,
                    "__component": "loadouts.forth-slot",
                    "Forth_Slot_Item": "L132A1 White Smoke Grenade",
                    "Item_Amount": 2
                },
                {
                    "id": 2,
                    "__component": "loadouts.forth-slot",
                    "Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
                    "Item_Amount": 1
                },
                {
                    "id": 3,
                    "__component": "loadouts.forth-slot",
                    "Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
                    "Item_Amount": 1
                },
                {
                    "id": 1,
                    "__component": "loadouts.fifth-slot",
                    "Fith_Slot_Item": "Field Dressing",
                    "Item_Amount": 2
                },
                {
                    "id": 1,
                    "__component": "loadouts.sixth-slot",
                    "Sixth_Slot_Item": "Field Binoculars",
                    "Item_Amount": 1
                },
                {
                    "id": 2,
                    "__component": "loadouts.sixth-slot",
                    "Sixth_Slot_Item": "Rally Point",
                    "Item_Amount": 1
                }
            ],
            "localizations": {
                "data": []
            }
        }
    },
    "meta": {}
}
MatDoak
  • 132
  • 5
  • 17

1 Answers1

1

You are missing attributes in object. Try changing

return res.data.British_Roles;

to

return res.data.attributes.British_Roles;

In future, always try to debug by adding a console.log before the return value, to ensure you are returning the correct values.

const fetcher = async (url, key) => {
  const res = await axios.get(url, {
    headers: {
      Authorization: `Bearer ${key}`,
      "Content-Type": "application/json",
    },
  });

  //so you know the error occurs here due to missing 'attributes'
  console.log(res.data.attributes.British_Roles)
  return res.data.attributes.British_Roles;
};

const response = {
    "data": {
        "id": 1,
        "attributes": {
            "Role_Name": "British Squad Lead (Iron Sights)",
            "createdAt": "2022-02-05T05:55:35.926Z",
            "updatedAt": "2022-02-05T05:55:38.194Z",
            "publishedAt": "2022-02-05T05:55:38.184Z",
            "locale": "en",
            "British_Roles": [
                {
                    "id": 1,
                    "role_name": "British Squad Lead (Iron Sights)",
                    "Primary": "L85A2 + Foregrip + Bipod",
                    "Primary_Sights": "Iron Sights",
                    "Primary_Firing_Modes": "Auto/Single",
                    "Primary_Magazine_Amount": 7,
                    "Primary_Magazine_Round_Amount": 30,
                    "Secondary": "L131A1",
                    "Secondary_Sights": "Iron Sights",
                    "Secondary_Firing_Modes": "Single",
                    "Secondary_Magazine_Amount": 2,
                    "Secondary_Magazine_Round_Amount": null,
                    "Secondary_Knife": "SA80 Bayonet"
                }
            ],
            "British_Role_Extras": [
                {
                    "id": 1,
                    "__component": "loadouts.third-slot",
                    "Third_Slot_Item": "L109A1 Fragmentation Grenade",
                    "Item_Amount": 2
                },
                {
                    "id": 1,
                    "__component": "loadouts.forth-slot",
                    "Forth_Slot_Item": "L132A1 White Smoke Grenade",
                    "Item_Amount": 2
                },
                {
                    "id": 2,
                    "__component": "loadouts.forth-slot",
                    "Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
                    "Item_Amount": 1
                },
                {
                    "id": 3,
                    "__component": "loadouts.forth-slot",
                    "Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
                    "Item_Amount": 1
                },
                {
                    "id": 1,
                    "__component": "loadouts.fifth-slot",
                    "Fith_Slot_Item": "Field Dressing",
                    "Item_Amount": 2
                },
                {
                    "id": 1,
                    "__component": "loadouts.sixth-slot",
                    "Sixth_Slot_Item": "Field Binoculars",
                    "Item_Amount": 1
                },
                {
                    "id": 2,
                    "__component": "loadouts.sixth-slot",
                    "Sixth_Slot_Item": "Rally Point",
                    "Item_Amount": 1
                }
            ],
            "localizations": {
                "data": []
            }
        }
    },
    "meta": {}
}

console.log(response.data.attributes.British_Roles)
Someone Special
  • 12,479
  • 7
  • 45
  • 76
  • can't believe I missed that thanks and thanks for the console log tip I will remember that one! That has fixed the loading issue, but now it's saying that `British_Roles` is undefined? – MatDoak Feb 05 '22 at 08:42
  • which line showing the error? Unless your axios is not returning the right response, else base on the object you showed, I've demonstrated that the `response.data.attributes.British_roles` works. – Someone Special Feb 05 '22 at 08:46
  • `var roles = JSON.parse(data)` can be omitted by the way. – Someone Special Feb 05 '22 at 08:49
  • I removed the `var roles = JSON.parse(data)` But the issue is coming from the ` return res.data.attributes.British_Roles;` line on the fetcher – MatDoak Feb 05 '22 at 09:09
  • do a console.log on `res` and see if there's error – Someone Special Feb 05 '22 at 09:12
  • Okay did that https://imgur.com/a/wRehTfU thats what the console spits out I cannot open the data tab any further – MatDoak Feb 05 '22 at 09:18
  • well then u got to open up `data` and see fht object structure.. – Someone Special Feb 05 '22 at 09:20
  • If I make the console log `res.data` I can clearly see all the response including the `British_Roles` but it is an array, could this possibly cause an undefined error? To add to this if I add `attributes` to the console log it then does return an undefined for a weird reason – MatDoak Feb 05 '22 at 09:23
  • You have to screenshot that since I don't know what you get from response. – Someone Special Feb 05 '22 at 09:37
  • Okay, I've eddited the original code to show the changes I have made, half of the issue was I wasn't digging in enough into the `res` instead of `res.data` it should have been `res.data.data` Once I made the return `res.data.data.attributes` I am now getting an error stating that the map function is not a function `TypeError: data.map is not a function` console https://imgur.com/a/jqwBdk4 – MatDoak Feb 05 '22 at 09:43
  • 1
    Please be consistent with your requirement. `data.data.attributes.British_roles` is an array and you can use data.map. `data.data.attributes` is an object and you cannot use map. If you want to return `data.data.attributes` then you need to use `data.British_Roles.map`. IF you want to use `data.map` then you need to return `res.data.data.attributes.British_Roles`, you get the idea? – Someone Special Feb 05 '22 at 09:49
  • Everything is working I appreciate the help. And sorry for the mismatch I tend to confuse myself at times haha – MatDoak Feb 05 '22 at 09:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241749/discussion-between-matdoak-and-someone-special). – MatDoak Feb 05 '22 at 11:42