Subjects Endpoint not working correct? (Code review needed)

Hey there,
I am currently participating in a coding bootcamp and I’m building a mobile app for WaniKani using the API with Next.js for my final project. I just started connecting the API to my app like this:

export default function HomePage() {
  const [loadingIsVisible, setLoadingIsVisible] = useState(true);
  const [apiToken, setApiToken] = useLocalStorageState("apiToken", {
    defaultValue: "",
  });
  const [userData, setUserData] = useLocalStorageState("userData", {
    defaultValue: [],
  });
  const [assignmentData, setAssignmentData] = useLocalStorageState(
    "assignmentData",
    { defaultValue: [] }
  );
  const [subjectRadicalData, setSubjectRadicalData] = useLocalStorageState(
    "subjectRadicalData",
    {
      defaultValue: [],
    }
  );
  const [subjectKanjiData, setSubjectKanjiData] = useLocalStorageState(
    "subjectKanjiData",
    {
      defaultValue: [],
    }
  );
  const [subjectVocabularyData, setSubjectVocabularyData] =
    useLocalStorageState("subjectVocabularyData", {
      defaultValue: [],
    });
  const [subjectKanaVocabularyData, setSubjectKanaVocabularyData] =
    useLocalStorageState("subjectKanaVocabularyData", {
      defaultValue: [],
    });
  const endpointPaths = [
    "user",
    "assignments",
    "subjects?types=radical",
    "subjects?types=kanji",
    "subjects?types=vocabulary",
    "subjects?types=kana_vocabulary",
  ];
  const router = useRouter();

  useEffect(() => {
    if (apiToken === "") {
      setLoadingIsVisible(false);
    } else {
      setLoadingIsVisible(true);
      fetchUserObjects();
    }
  }, [apiToken]);

  function fetchUserObjects() {
    const fetchPromises = endpointPaths.map((path) => {
      const requestHeaders = new Headers({
        "Wanikani-Revision": "20170710",
        Authorization: "Bearer " + apiToken,
      });

      const apiEndpoint = new Request(`https://api.wanikani.com/v2/${path}`, {
        method: "GET",
        headers: requestHeaders,
      });

      return fetch(apiEndpoint)
        .then((response) => response.json())
        .then((responseBody) => {
          switch (path) {
            case "user":
              setUserData(responseBody.data);
              break;
            case "assignments":
              setAssignmentData(responseBody.data);
              break;
            case "subjects?types=radical":
              setSubjectRadicalData(responseBody.data);
              break;
            case "subjects?types=kanji":
              setSubjectKanjiData(responseBody.data);
              break;
            case "subjects?types=vocabulary":
              setSubjectVocabularyData(responseBody.data);
              break;
            case "subjects?types=kana_vocabulary":
              setSubjectKanaVocabularyData(responseBody.data);
              break;
            default:
              break;
          }
        })
        .catch((error) => {
          console.error(`Error fetching ${path} data:`, error);
        });
    });

    Promise.all(fetchPromises)
      .then(() => {
        setTimeout(() => {
          router.push("/dashboard");
        }, 2000);
      })
      .catch((error) => {
        console.error("Error fetching user data:", error);
      });
  }

  function handleSubmitAPITokenInput(event) {
    event.preventDefault();
    const tokenInput = event.target.elements.tokenInput.value;
    setApiToken(tokenInput);
  }

  return (
    <>
      <AppHeader />
      <WelcomeMessage>いらっしゃいませ !</WelcomeMessage>
      <LoadingComponent loadingIsVisible={loadingIsVisible} />
      <APITokenInputField
        onSubmitAPITokenInput={handleSubmitAPITokenInput}
        inputFieldIsVisible={!loadingIsVisible}
      />
    </>
  );
}

All endpoints return the specified data, except for subjects type vocabulary. Does anyone here have a clue why that is? I can’t find the mistake I made.

You can find the Github Repo here, last commit was just pushed. :innocent:

Thank you in advance!
xx Rylie

1 Like

WK is “working on it”

https://media.tenor.com/Lktxi13nv_AAAAAC/quotation-marks-chris-farley.gif

2 Likes

So no way for me to retrieve all vocabulary subjects right now? I saw that the reviews endpoint is not working right now, but I didn’t realize that that is the case for subjects?types=vocabulary too.

Because it’s not.

Your code “should” work, as in, the way it was written can achieve a result. However, you can’t fetch the whole data with one request each. There are about 6500 vocabulary items currently on wk, and afaik the api gives it to you in batches of a 1000 or so. Unless you need to specifically write the fetching yourself, I’d suggest using some premade library for this, as there are plenty for javascript out there.

Also, if you want every single subject type, I recommend instead fetching them in one go, and sorting them out yourself, as that will probably be faster on your end.

2 Likes

The thing is that I retrieve literally nothing back. All other subjects are being saved to local storage like I intended to, just the subjects vocabulary makes problems.


As you can see the last subject array is empty whereas the others aren’t and I don’t understand why.

Have you checked the Network tab inside the console to see what actually gets returned?

1 Like

You’re right. I just tried a console.log and apparently the data is returned. No idea why it doesn’t save to local storage then though, but that seems to be a problem on my side and not on WK, so I’ll ask my coaches about that. :slight_smile:

1 Like

Oh wait a sec, could it be that you just run out of space? Localstorage has an upper limit of 10MB, how big is the data that’s trying to get stored?

5 Likes

Correct. At least that’s how it worked the last time I tried it. Does it return an error HTTP code for bigger queries or still just 200 and only the head 1000 entries? I remember it used to just return 1000 entries with HTTP 200 even if you ask for more so any sanitation needs to be done on client side @rylie091 .

dang, I didn’t realize that. That was my mistake! Thank you.

“It” can be anything though

1 Like