From feb4c434d1723a38a8991e1be0fc8ca5536d9b08 Mon Sep 17 00:00:00 2001
From: abias <abias1122@gmail.com>
Date: Mon, 29 May 2023 20:40:00 -0400
Subject: [PATCH] Refactor route data

---
 src/server/index.tsx                          |  21 +++-
 .../components/community/communities.tsx      |  20 +++-
 src/shared/components/community/community.tsx |  53 +++++----
 src/shared/components/home/admin-settings.tsx |  38 +++---
 src/shared/components/home/home.tsx           |  50 ++++----
 src/shared/components/home/instances.tsx      |  24 ++--
 src/shared/components/modlog.tsx              |  69 ++++++-----
 src/shared/components/person/inbox.tsx        | 109 ++++++++++--------
 src/shared/components/person/profile.tsx      |  17 ++-
 .../person/registration-applications.tsx      |  41 ++++---
 src/shared/components/person/reports.tsx      | 109 ++++++++++--------
 src/shared/components/post/create-post.tsx    |  29 ++---
 src/shared/components/post/post.tsx           |  41 ++++---
 .../create-private-message.tsx                |  26 +++--
 src/shared/components/search.tsx              |  95 +++++++++------
 src/shared/interfaces.ts                      |   8 +-
 src/shared/routes.ts                          |   7 +-
 src/shared/utils.ts                           |   6 +-
 18 files changed, 453 insertions(+), 310 deletions(-)

diff --git a/src/server/index.tsx b/src/server/index.tsx
index a93595e..4ab4f76 100644
--- a/src/server/index.tsx
+++ b/src/server/index.tsx
@@ -129,7 +129,7 @@ server.get("/*", async (req, res) => {
     // This bypasses errors, so that the client can hit the error on its own,
     // in order to remove the jwt on the browser. Necessary for wrong jwts
     let site: GetSiteResponse | undefined = undefined;
-    let routeData: any[] = [];
+    let routeData: Record<string, any> = {};
     let errorPageData: ErrorPageData | undefined;
     try {
       let try_site: any = await client.getSite(getSiteForm);
@@ -160,18 +160,27 @@ server.get("/*", async (req, res) => {
         };
 
         if (activeRoute?.fetchInitialData) {
-          routeData = await Promise.all([
-            ...activeRoute.fetchInitialData(initialFetchReq),
-          ]);
+          const routeDataKeysAndVals = await Promise.all(
+            Object.entries(activeRoute.fetchInitialData(initialFetchReq)).map(
+              async ([key, val]) => [key, await val]
+            )
+          );
+
+          routeData = routeDataKeysAndVals.reduce((acc, [key, val]) => {
+            acc[key] = val;
+
+            return acc;
+          }, {});
         }
       }
     } catch (error) {
       errorPageData = getErrorPageData(error, site);
     }
 
+    const error = Object.values(routeData).find(val => val?.error)?.error;
+
     // Redirect to the 404 if there's an API error
-    if (routeData[0] && routeData[0].error) {
-      const error = routeData[0].error;
+    if (error) {
       console.error(error);
       if (error === "instance_is_private") {
         return res.redirect(`/signup`);
diff --git a/src/shared/components/community/communities.tsx b/src/shared/components/community/communities.tsx
index 2e147b8..53e0e96 100644
--- a/src/shared/components/community/communities.tsx
+++ b/src/shared/components/community/communities.tsx
@@ -16,6 +16,7 @@ import { i18n } from "../../i18next";
 import { WebSocketService } from "../../services";
 import {
   QueryParams,
+  WithPromiseKeys,
   getPageFromString,
   getQueryParams,
   getQueryString,
@@ -36,6 +37,10 @@ import { CommunityLink } from "./community-link";
 
 const communityLimit = 50;
 
+interface CommunitiesData {
+  listCommunitiesResponse: ListCommunitiesResponse;
+}
+
 interface CommunitiesState {
   listCommunitiesResponse?: ListCommunitiesResponse;
   loading: boolean;
@@ -88,7 +93,7 @@ function refetch() {
 
 export class Communities extends Component<any, CommunitiesState> {
   private subscription?: Subscription;
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<CommunitiesData>(this.context);
   state: CommunitiesState = {
     loading: true,
     siteRes: this.isoData.site_res,
@@ -105,10 +110,11 @@ export class Communities extends Component<any, CommunitiesState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path === this.context.router.route.match.url) {
-      const listRes = this.isoData.routeData[0] as ListCommunitiesResponse;
+      const { listCommunitiesResponse } = this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        listCommunitiesResponse: listRes,
+        listCommunitiesResponse,
         loading: false,
       };
     } else {
@@ -312,7 +318,9 @@ export class Communities extends Component<any, CommunitiesState> {
     query: { listingType, page },
     client,
     auth,
-  }: InitialFetchRequest<QueryParams<CommunitiesProps>>): Promise<any>[] {
+  }: InitialFetchRequest<
+    QueryParams<CommunitiesProps>
+  >): WithPromiseKeys<CommunitiesData> {
     const listCommunitiesForm: ListCommunities = {
       type_: getListingTypeFromQuery(listingType),
       sort: "TopMonth",
@@ -321,7 +329,9 @@ export class Communities extends Component<any, CommunitiesState> {
       auth: auth,
     };
 
-    return [client.listCommunities(listCommunitiesForm)];
+    return {
+      listCommunitiesResponse: client.listCommunities(listCommunitiesForm),
+    };
   }
 
   parseMessage(msg: any) {
diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx
index af562c1..f3ab1e2 100644
--- a/src/shared/components/community/community.tsx
+++ b/src/shared/components/community/community.tsx
@@ -33,6 +33,7 @@ import {
 import { UserService, WebSocketService } from "../../services";
 import {
   QueryParams,
+  WithPromiseKeys,
   commentsToFlatNodes,
   communityRSSUrl,
   createCommentLikeRes,
@@ -76,6 +77,12 @@ import { SiteSidebar } from "../home/site-sidebar";
 import { PostListings } from "../post/post-listings";
 import { CommunityLink } from "./community-link";
 
+interface CommunityData {
+  communityResponse: GetCommunityResponse;
+  postsResponse?: GetPostsResponse;
+  commentsResponse?: GetCommentsResponse;
+}
+
 interface State {
   communityRes?: GetCommunityResponse;
   communityLoading: boolean;
@@ -115,7 +122,7 @@ export class Community extends Component<
   RouteComponentProps<{ name: string }>,
   State
 > {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<CommunityData>(this.context);
   private subscription?: Subscription;
   state: State = {
     communityLoading: true,
@@ -137,23 +144,20 @@ export class Community extends Component<
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
+      const { communityResponse, commentsResponse, postsResponse } =
+        this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        communityRes: this.isoData.routeData[0] as GetCommunityResponse,
+        communityRes: communityResponse,
       };
-      const postsRes = this.isoData.routeData[1] as
-        | GetPostsResponse
-        | undefined;
-      const commentsRes = this.isoData.routeData[2] as
-        | GetCommentsResponse
-        | undefined;
-
-      if (postsRes) {
-        this.state = { ...this.state, posts: postsRes.posts };
+
+      if (postsResponse) {
+        this.state = { ...this.state, posts: postsResponse.posts };
       }
 
-      if (commentsRes) {
-        this.state = { ...this.state, comments: commentsRes.comments };
+      if (commentsResponse) {
+        this.state = { ...this.state, comments: commentsResponse.comments };
       }
 
       this.state = {
@@ -189,16 +193,16 @@ export class Community extends Component<
     path,
     query: { dataType: urlDataType, page: urlPage, sort: urlSort },
     auth,
-  }: InitialFetchRequest<QueryParams<CommunityProps>>): Promise<any>[] {
+  }: InitialFetchRequest<
+    QueryParams<CommunityProps>
+  >): WithPromiseKeys<CommunityData> {
     const pathSplit = path.split("/");
-    const promises: Promise<any>[] = [];
 
     const communityName = pathSplit[2];
     const communityForm: GetCommunity = {
       name: communityName,
       auth,
     };
-    promises.push(client.getCommunity(communityForm));
 
     const dataType = getDataTypeFromQuery(urlDataType);
 
@@ -206,6 +210,9 @@ export class Community extends Component<
 
     const page = getPageFromString(urlPage);
 
+    let postsResponse: Promise<GetPostsResponse> | undefined = undefined;
+    let commentsResponse: Promise<GetCommentsResponse> | undefined = undefined;
+
     if (dataType === DataType.Post) {
       const getPostsForm: GetPosts = {
         community_name: communityName,
@@ -216,8 +223,8 @@ export class Community extends Component<
         saved_only: false,
         auth,
       };
-      promises.push(client.getPosts(getPostsForm));
-      promises.push(Promise.resolve());
+
+      postsResponse = client.getPosts(getPostsForm);
     } else {
       const getCommentsForm: GetComments = {
         community_name: communityName,
@@ -228,11 +235,15 @@ export class Community extends Component<
         saved_only: false,
         auth,
       };
-      promises.push(Promise.resolve());
-      promises.push(client.getComments(getCommentsForm));
+
+      commentsResponse = client.getComments(getCommentsForm);
     }
 
-    return promises;
+    return {
+      communityResponse: client.getCommunity(communityForm),
+      commentsResponse,
+      postsResponse,
+    };
   }
 
   get documentTitle(): string {
diff --git a/src/shared/components/home/admin-settings.tsx b/src/shared/components/home/admin-settings.tsx
index d266db5..4419cf3 100644
--- a/src/shared/components/home/admin-settings.tsx
+++ b/src/shared/components/home/admin-settings.tsx
@@ -2,7 +2,6 @@ import autosize from "autosize";
 import { Component, linkEvent } from "inferno";
 import {
   BannedPersonsResponse,
-  GetBannedPersons,
   GetFederatedInstancesResponse,
   GetSiteResponse,
   PersonView,
@@ -16,6 +15,7 @@ import { i18n } from "../../i18next";
 import { InitialFetchRequest } from "../../interfaces";
 import { WebSocketService } from "../../services";
 import {
+  WithPromiseKeys,
   capitalizeFirstLetter,
   isBrowser,
   myAuth,
@@ -35,6 +35,11 @@ import RateLimitForm from "./rate-limit-form";
 import { SiteForm } from "./site-form";
 import { TaglineForm } from "./tagline-form";
 
+interface AdminSettingsData {
+  bannedPersonsResponse: BannedPersonsResponse;
+  federatedInstancesResponse: GetFederatedInstancesResponse;
+}
+
 interface AdminSettingsState {
   siteRes: GetSiteResponse;
   instancesRes?: GetFederatedInstancesResponse;
@@ -45,7 +50,7 @@ interface AdminSettingsState {
 
 export class AdminSettings extends Component<any, AdminSettingsState> {
   private siteConfigTextAreaId = `site-config-${randomStr()}`;
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<AdminSettingsData>(this.context);
   private subscription?: Subscription;
   state: AdminSettingsState = {
     siteRes: this.isoData.site_res,
@@ -62,11 +67,13 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path == this.context.router.route.match.url) {
+      const { bannedPersonsResponse, federatedInstancesResponse } =
+        this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        banned: (this.isoData.routeData[0] as BannedPersonsResponse).banned,
-        instancesRes: this.isoData
-          .routeData[1] as GetFederatedInstancesResponse,
+        banned: bannedPersonsResponse.banned,
+        instancesRes: federatedInstancesResponse,
         loading: false,
       };
     } else {
@@ -84,17 +91,16 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
     }
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let promises: Promise<any>[] = [];
-
-    let auth = req.auth;
-    if (auth) {
-      let bannedPersonsForm: GetBannedPersons = { auth };
-      promises.push(req.client.getBannedPersons(bannedPersonsForm));
-      promises.push(req.client.getFederatedInstances({ auth }));
-    }
-
-    return promises;
+  static fetchInitialData({
+    auth,
+    client,
+  }: InitialFetchRequest): WithPromiseKeys<AdminSettingsData> {
+    return {
+      bannedPersonsResponse: client.getBannedPersons({ auth: auth as string }),
+      federatedInstancesResponse: client.getFederatedInstances({
+        auth: auth as string,
+      }) as Promise<GetFederatedInstancesResponse>,
+    };
   }
 
   componentDidMount() {
diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx
index 52a8212..e85c3e6 100644
--- a/src/shared/components/home/home.tsx
+++ b/src/shared/components/home/home.tsx
@@ -69,6 +69,7 @@ import {
   toast,
   trendingFetchLimit,
   updatePersonBlock,
+  WithPromiseKeys,
   wsClient,
   wsSubscribe,
 } from "../../utils";
@@ -103,6 +104,12 @@ interface HomeProps {
   page: number;
 }
 
+interface HomeData {
+  postsResponse?: GetPostsResponse;
+  commentsResponse?: GetCommentsResponse;
+  trendingResponse: ListCommunitiesResponse;
+}
+
 function getDataTypeFromQuery(type?: string): DataType {
   return type ? DataType[type] : DataType.Post;
 }
@@ -237,7 +244,7 @@ function getRss(listingType: ListingType) {
 }
 
 export class Home extends Component<any, HomeState> {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<HomeData>(this.context);
   private subscription?: Subscription;
   state: HomeState = {
     trendingCommunities: [],
@@ -264,22 +271,15 @@ export class Home extends Component<any, HomeState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path === this.context.router.route.match.url) {
-      const postsRes = this.isoData.routeData[0] as
-        | GetPostsResponse
-        | undefined;
-      const commentsRes = this.isoData.routeData[1] as
-        | GetCommentsResponse
-        | undefined;
-      const trendingRes = this.isoData.routeData[2] as
-        | ListCommunitiesResponse
-        | undefined;
-
-      if (postsRes) {
-        this.state = { ...this.state, posts: postsRes.posts };
+      const { trendingResponse, commentsResponse, postsResponse } =
+        this.isoData.routeData;
+
+      if (postsResponse) {
+        this.state = { ...this.state, posts: postsResponse.posts };
       }
 
-      if (commentsRes) {
-        this.state = { ...this.state, comments: commentsRes.comments };
+      if (commentsResponse) {
+        this.state = { ...this.state, comments: commentsResponse.comments };
       }
 
       if (isBrowser()) {
@@ -290,7 +290,7 @@ export class Home extends Component<any, HomeState> {
       const taglines = this.state?.siteRes?.taglines ?? [];
       this.state = {
         ...this.state,
-        trendingCommunities: trendingRes?.communities ?? [],
+        trendingCommunities: trendingResponse?.communities ?? [],
         loading: false,
         tagline: getRandomFromList(taglines)?.content,
       };
@@ -317,7 +317,7 @@ export class Home extends Component<any, HomeState> {
     client,
     auth,
     query: { dataType: urlDataType, listingType, page: urlPage, sort: urlSort },
-  }: InitialFetchRequest<QueryParams<HomeProps>>): Promise<any>[] {
+  }: InitialFetchRequest<QueryParams<HomeProps>>): WithPromiseKeys<HomeData> {
     const dataType = getDataTypeFromQuery(urlDataType);
 
     // TODO figure out auth default_listingType, default_sort_type
@@ -328,6 +328,9 @@ export class Home extends Component<any, HomeState> {
 
     const promises: Promise<any>[] = [];
 
+    let postsResponse: Promise<GetPostsResponse> | undefined = undefined;
+    let commentsResponse: Promise<GetCommentsResponse> | undefined = undefined;
+
     if (dataType === DataType.Post) {
       const getPostsForm: GetPosts = {
         type_,
@@ -338,8 +341,7 @@ export class Home extends Component<any, HomeState> {
         auth,
       };
 
-      promises.push(client.getPosts(getPostsForm));
-      promises.push(Promise.resolve());
+      postsResponse = client.getPosts(getPostsForm);
     } else {
       const getCommentsForm: GetComments = {
         page,
@@ -349,8 +351,8 @@ export class Home extends Component<any, HomeState> {
         saved_only: false,
         auth,
       };
-      promises.push(Promise.resolve());
-      promises.push(client.getComments(getCommentsForm));
+
+      commentsResponse = client.getComments(getCommentsForm);
     }
 
     const trendingCommunitiesForm: ListCommunities = {
@@ -361,7 +363,11 @@ export class Home extends Component<any, HomeState> {
     };
     promises.push(client.listCommunities(trendingCommunitiesForm));
 
-    return promises;
+    return {
+      trendingResponse: client.listCommunities(trendingCommunitiesForm),
+      commentsResponse,
+      postsResponse,
+    };
   }
 
   get documentTitle(): string {
diff --git a/src/shared/components/home/instances.tsx b/src/shared/components/home/instances.tsx
index 674374d..fd1ed61 100644
--- a/src/shared/components/home/instances.tsx
+++ b/src/shared/components/home/instances.tsx
@@ -12,6 +12,7 @@ import { i18n } from "../../i18next";
 import { InitialFetchRequest } from "../../interfaces";
 import { WebSocketService } from "../../services";
 import {
+  WithPromiseKeys,
   isBrowser,
   relTags,
   setIsoData,
@@ -21,6 +22,10 @@ import {
 } from "../../utils";
 import { HtmlTags } from "../common/html-tags";
 
+interface InstancesData {
+  federatedInstancesResponse: GetFederatedInstancesResponse;
+}
+
 interface InstancesState {
   siteRes: GetSiteResponse;
   instancesRes?: GetFederatedInstancesResponse;
@@ -28,7 +33,7 @@ interface InstancesState {
 }
 
 export class Instances extends Component<any, InstancesState> {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<InstancesData>(this.context);
   state: InstancesState = {
     siteRes: this.isoData.site_res,
     loading: true,
@@ -45,8 +50,7 @@ export class Instances extends Component<any, InstancesState> {
     if (this.isoData.path == this.context.router.route.match.url) {
       this.state = {
         ...this.state,
-        instancesRes: this.isoData
-          .routeData[0] as GetFederatedInstancesResponse,
+        instancesRes: this.isoData.routeData.federatedInstancesResponse,
         loading: false,
       };
     } else {
@@ -54,12 +58,14 @@ export class Instances extends Component<any, InstancesState> {
     }
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let promises: Promise<any>[] = [];
-
-    promises.push(req.client.getFederatedInstances({}));
-
-    return promises;
+  static fetchInitialData({
+    client,
+  }: InitialFetchRequest): WithPromiseKeys<InstancesData> {
+    return {
+      federatedInstancesResponse: client.getFederatedInstances(
+        {}
+      ) as Promise<GetFederatedInstancesResponse>,
+    };
   }
 
   get documentTitle(): string {
diff --git a/src/shared/components/modlog.tsx b/src/shared/components/modlog.tsx
index ef28816..cb4b37f 100644
--- a/src/shared/components/modlog.tsx
+++ b/src/shared/components/modlog.tsx
@@ -39,6 +39,7 @@ import { WebSocketService } from "../services";
 import {
   Choice,
   QueryParams,
+  WithPromiseKeys,
   amAdmin,
   amMod,
   debounce,
@@ -83,6 +84,13 @@ type View =
   | AdminPurgePostView
   | AdminPurgeCommentView;
 
+interface ModlogData {
+  modlogResponse: GetModlogResponse;
+  communityResponse?: GetCommunityResponse;
+  modUserResponse?: GetPersonDetailsResponse;
+  userResponse?: GetPersonDetailsResponse;
+}
+
 interface ModlogType {
   id: number;
   type_: ModlogActionType;
@@ -642,7 +650,7 @@ export class Modlog extends Component<
   RouteComponentProps<{ communityId?: string }>,
   ModlogState
 > {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<ModlogData>(this.context);
   private subscription?: Subscription;
 
   state: ModlogState = {
@@ -667,35 +675,35 @@ export class Modlog extends Component<
 
     // Only fetch the data if coming from another route
     if (this.isoData.path === this.context.router.route.match.url) {
+      const {
+        modlogResponse,
+        communityResponse,
+        modUserResponse,
+        userResponse,
+      } = this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        res: this.isoData.routeData[0] as GetModlogResponse,
+        res: modlogResponse,
       };
 
-      const communityRes: GetCommunityResponse | undefined =
-        this.isoData.routeData[1];
-
       // Getting the moderators
       this.state = {
         ...this.state,
-        communityMods: communityRes?.moderators,
+        communityMods: communityResponse?.moderators,
       };
 
-      const filteredModRes: GetPersonDetailsResponse | undefined =
-        this.isoData.routeData[2];
-      if (filteredModRes) {
+      if (modUserResponse) {
         this.state = {
           ...this.state,
-          modSearchOptions: [personToChoice(filteredModRes.person_view)],
+          modSearchOptions: [personToChoice(modUserResponse.person_view)],
         };
       }
 
-      const filteredUserRes: GetPersonDetailsResponse | undefined =
-        this.isoData.routeData[3];
-      if (filteredUserRes) {
+      if (userResponse) {
         this.state = {
           ...this.state,
-          userSearchOptions: [personToChoice(filteredUserRes.person_view)],
+          userSearchOptions: [personToChoice(userResponse.person_view)],
         };
       }
 
@@ -986,9 +994,10 @@ export class Modlog extends Component<
     query: { modId: urlModId, page, userId: urlUserId, actionType },
     auth,
     site,
-  }: InitialFetchRequest<QueryParams<ModlogProps>>): Promise<any>[] {
+  }: InitialFetchRequest<
+    QueryParams<ModlogProps>
+  >): WithPromiseKeys<ModlogData> {
     const pathSplit = path.split("/");
-    const promises: Promise<any>[] = [];
     const communityId = getIdFromString(pathSplit[2]);
     const modId = !site.site_view.local_site.hide_modlog_mod_names
       ? getIdFromString(urlModId)
@@ -1005,41 +1014,47 @@ export class Modlog extends Component<
       auth,
     };
 
-    promises.push(client.getModlog(modlogForm));
+    let communityResponse: Promise<GetCommunityResponse> | undefined =
+      undefined;
 
     if (communityId) {
       const communityForm: GetCommunity = {
         id: communityId,
         auth,
       };
-      promises.push(client.getCommunity(communityForm));
-    } else {
-      promises.push(Promise.resolve());
+
+      communityResponse = client.getCommunity(communityForm);
     }
 
+    let modUserResponse: Promise<GetPersonDetailsResponse> | undefined =
+      undefined;
+
     if (modId) {
       const getPersonForm: GetPersonDetails = {
         person_id: modId,
         auth,
       };
 
-      promises.push(client.getPersonDetails(getPersonForm));
-    } else {
-      promises.push(Promise.resolve());
+      modUserResponse = client.getPersonDetails(getPersonForm);
     }
 
+    let userResponse: Promise<GetPersonDetailsResponse> | undefined = undefined;
+
     if (userId) {
       const getPersonForm: GetPersonDetails = {
         person_id: userId,
         auth,
       };
 
-      promises.push(client.getPersonDetails(getPersonForm));
-    } else {
-      promises.push(Promise.resolve());
+      userResponse = client.getPersonDetails(getPersonForm);
     }
 
-    return promises;
+    return {
+      modlogResponse: client.getModlog(modlogForm),
+      communityResponse,
+      modUserResponse,
+      userResponse,
+    };
   }
 
   parseMessage(msg: any) {
diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx
index 8145ab6..6393fc6 100644
--- a/src/shared/components/person/inbox.tsx
+++ b/src/shared/components/person/inbox.tsx
@@ -29,6 +29,7 @@ import { i18n } from "../../i18next";
 import { CommentViewType, InitialFetchRequest } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
+  WithPromiseKeys,
   commentsToFlatNodes,
   createCommentLikeRes,
   editCommentRes,
@@ -69,6 +70,13 @@ enum ReplyEnum {
   Mention,
   Message,
 }
+
+interface InboxData {
+  repliesResponse: GetRepliesResponse;
+  personMentionsResponse: GetPersonMentionsResponse;
+  privateMessagesResponse: PrivateMessagesResponse;
+}
+
 type ReplyType = {
   id: number;
   type_: ReplyEnum;
@@ -90,7 +98,7 @@ interface InboxState {
 }
 
 export class Inbox extends Component<any, InboxState> {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<InboxData>(this.context);
   private subscription?: Subscription;
   state: InboxState = {
     unreadOrAll: UnreadOrAll.Unread,
@@ -115,17 +123,18 @@ export class Inbox extends Component<any, InboxState> {
     this.subscription = wsSubscribe(this.parseMessage);
 
     // Only fetch the data if coming from another route
-    if (this.isoData.path == this.context.router.route.match.url) {
+    if (this.isoData.path === this.context.router.route.match.url) {
+      const {
+        personMentionsResponse,
+        privateMessagesResponse,
+        repliesResponse,
+      } = this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        replies:
-          (this.isoData.routeData[0] as GetRepliesResponse).replies || [],
-        mentions:
-          (this.isoData.routeData[1] as GetPersonMentionsResponse).mentions ||
-          [],
-        messages:
-          (this.isoData.routeData[2] as PrivateMessagesResponse)
-            .private_messages || [],
+        replies: repliesResponse.replies ?? [],
+        mentions: personMentionsResponse.mentions ?? [],
+        messages: privateMessagesResponse.private_messages ?? [],
         loading: false,
       };
       this.state = { ...this.state, combined: this.buildCombined() };
@@ -481,53 +490,51 @@ export class Inbox extends Component<any, InboxState> {
     i.refetch();
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let promises: Promise<any>[] = [];
-
-    let sort: CommentSortType = "New";
-    let auth = req.auth;
-
-    if (auth) {
-      // It can be /u/me, or /username/1
-      let repliesForm: GetReplies = {
-        sort: "New",
-        unread_only: true,
-        page: 1,
-        limit: fetchLimit,
-        auth,
-      };
-      promises.push(req.client.getReplies(repliesForm));
+  static fetchInitialData({
+    auth,
+    client,
+  }: InitialFetchRequest): WithPromiseKeys<InboxData> {
+    const sort: CommentSortType = "New";
+
+    // It can be /u/me, or /username/1
+    const repliesForm: GetReplies = {
+      sort,
+      unread_only: true,
+      page: 1,
+      limit: fetchLimit,
+      auth: auth as string,
+    };
 
-      let personMentionsForm: GetPersonMentions = {
-        sort,
-        unread_only: true,
-        page: 1,
-        limit: fetchLimit,
-        auth,
-      };
-      promises.push(req.client.getPersonMentions(personMentionsForm));
+    const personMentionsForm: GetPersonMentions = {
+      sort,
+      unread_only: true,
+      page: 1,
+      limit: fetchLimit,
+      auth: auth as string,
+    };
 
-      let privateMessagesForm: GetPrivateMessages = {
-        unread_only: true,
-        page: 1,
-        limit: fetchLimit,
-        auth,
-      };
-      promises.push(req.client.getPrivateMessages(privateMessagesForm));
-    }
+    const privateMessagesForm: GetPrivateMessages = {
+      unread_only: true,
+      page: 1,
+      limit: fetchLimit,
+      auth: auth as string,
+    };
 
-    return promises;
+    return {
+      privateMessagesResponse: client.getPrivateMessages(privateMessagesForm),
+      personMentionsResponse: client.getPersonMentions(personMentionsForm),
+      repliesResponse: client.getReplies(repliesForm),
+    };
   }
 
   refetch() {
-    let sort = this.state.sort;
-    let unread_only = this.state.unreadOrAll == UnreadOrAll.Unread;
-    let page = this.state.page;
-    let limit = fetchLimit;
-    let auth = myAuth();
+    const { sort, page, unreadOrAll } = this.state;
+    const unread_only = unreadOrAll === UnreadOrAll.Unread;
+    const limit = fetchLimit;
+    const auth = myAuth();
 
     if (auth) {
-      let repliesForm: GetReplies = {
+      const repliesForm: GetReplies = {
         sort,
         unread_only,
         page,
@@ -536,7 +543,7 @@ export class Inbox extends Component<any, InboxState> {
       };
       WebSocketService.Instance.send(wsClient.getReplies(repliesForm));
 
-      let personMentionsForm: GetPersonMentions = {
+      const personMentionsForm: GetPersonMentions = {
         sort,
         unread_only,
         page,
@@ -547,7 +554,7 @@ export class Inbox extends Component<any, InboxState> {
         wsClient.getPersonMentions(personMentionsForm)
       );
 
-      let privateMessagesForm: GetPrivateMessages = {
+      const privateMessagesForm: GetPrivateMessages = {
         unread_only,
         page,
         limit,
diff --git a/src/shared/components/person/profile.tsx b/src/shared/components/person/profile.tsx
index 42c7c30..00a4419 100644
--- a/src/shared/components/person/profile.tsx
+++ b/src/shared/components/person/profile.tsx
@@ -29,6 +29,7 @@ import { InitialFetchRequest, PersonDetailsView } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
   QueryParams,
+  WithPromiseKeys,
   canMod,
   capitalizeFirstLetter,
   createCommentLikeRes,
@@ -67,6 +68,10 @@ import { CommunityLink } from "../community/community-link";
 import { PersonDetails } from "./person-details";
 import { PersonListing } from "./person-listing";
 
+interface ProfileData {
+  personResponse: GetPersonDetailsResponse;
+}
+
 interface ProfileState {
   personRes?: GetPersonDetailsResponse;
   loading: boolean;
@@ -152,7 +157,7 @@ export class Profile extends Component<
   RouteComponentProps<{ username: string }>,
   ProfileState
 > {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<ProfileData>(this.context);
   private subscription?: Subscription;
   state: ProfileState = {
     loading: true,
@@ -175,7 +180,7 @@ export class Profile extends Component<
     if (this.isoData.path === this.context.router.route.match.url) {
       this.state = {
         ...this.state,
-        personRes: this.isoData.routeData[0] as GetPersonDetailsResponse,
+        personRes: this.isoData.routeData.personResponse,
         loading: false,
       };
     } else {
@@ -223,7 +228,9 @@ export class Profile extends Component<
     path,
     query: { page, sort, view: urlView },
     auth,
-  }: InitialFetchRequest<QueryParams<ProfileProps>>): Promise<any>[] {
+  }: InitialFetchRequest<
+    QueryParams<ProfileProps>
+  >): WithPromiseKeys<ProfileData> {
     const pathSplit = path.split("/");
 
     const username = pathSplit[2];
@@ -238,7 +245,9 @@ export class Profile extends Component<
       auth,
     };
 
-    return [client.getPersonDetails(form)];
+    return {
+      personResponse: client.getPersonDetails(form),
+    };
   }
 
   componentDidMount() {
diff --git a/src/shared/components/person/registration-applications.tsx b/src/shared/components/person/registration-applications.tsx
index 39b6590..72ac501 100644
--- a/src/shared/components/person/registration-applications.tsx
+++ b/src/shared/components/person/registration-applications.tsx
@@ -13,6 +13,7 @@ import { i18n } from "../../i18next";
 import { InitialFetchRequest } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
+  WithPromiseKeys,
   fetchLimit,
   isBrowser,
   myAuth,
@@ -33,6 +34,10 @@ enum UnreadOrAll {
   All,
 }
 
+interface RegistrationApplicationsData {
+  listRegistrationApplicationsResponse: ListRegistrationApplicationsResponse;
+}
+
 interface RegistrationApplicationsState {
   listRegistrationApplicationsResponse?: ListRegistrationApplicationsResponse;
   siteRes: GetSiteResponse;
@@ -45,7 +50,7 @@ export class RegistrationApplications extends Component<
   any,
   RegistrationApplicationsState
 > {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<RegistrationApplicationsData>(this.context);
   private subscription?: Subscription;
   state: RegistrationApplicationsState = {
     siteRes: this.isoData.site_res,
@@ -63,11 +68,11 @@ export class RegistrationApplications extends Component<
     this.subscription = wsSubscribe(this.parseMessage);
 
     // Only fetch the data if coming from another route
-    if (this.isoData.path == this.context.router.route.match.url) {
+    if (this.isoData.path === this.context.router.route.match.url) {
       this.state = {
         ...this.state,
-        listRegistrationApplicationsResponse: this.isoData
-          .routeData[0] as ListRegistrationApplicationsResponse,
+        listRegistrationApplicationsResponse:
+          this.isoData.routeData.listRegistrationApplicationsResponse,
         loading: false,
       };
     } else {
@@ -192,21 +197,21 @@ export class RegistrationApplications extends Component<
     this.refetch();
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let promises: Promise<any>[] = [];
-
-    let auth = req.auth;
-    if (auth) {
-      let form: ListRegistrationApplications = {
-        unread_only: true,
-        page: 1,
-        limit: fetchLimit,
-        auth,
-      };
-      promises.push(req.client.listRegistrationApplications(form));
-    }
+  static fetchInitialData({
+    auth,
+    client,
+  }: InitialFetchRequest): WithPromiseKeys<RegistrationApplicationsData> {
+    const form: ListRegistrationApplications = {
+      unread_only: true,
+      page: 1,
+      limit: fetchLimit,
+      auth: auth as string,
+    };
 
-    return promises;
+    return {
+      listRegistrationApplicationsResponse:
+        client.listRegistrationApplications(form),
+    };
   }
 
   refetch() {
diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx
index 3c00f54..51b41c9 100644
--- a/src/shared/components/person/reports.tsx
+++ b/src/shared/components/person/reports.tsx
@@ -22,6 +22,7 @@ import { i18n } from "../../i18next";
 import { InitialFetchRequest } from "../../interfaces";
 import { UserService, WebSocketService } from "../../services";
 import {
+  WithPromiseKeys,
   amAdmin,
   fetchLimit,
   isBrowser,
@@ -60,6 +61,12 @@ enum MessageEnum {
   PrivateMessageReport,
 }
 
+interface ReportsData {
+  commentReportsResponse: ListCommentReportsResponse;
+  postReportsResponse: ListPostReportsResponse;
+  privateMessageReportsResponse?: ListPrivateMessageReportsResponse;
+}
+
 type ItemType = {
   id: number;
   type_: MessageEnum;
@@ -80,7 +87,7 @@ interface ReportsState {
 }
 
 export class Reports extends Component<any, ReportsState> {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<ReportsData>(this.context);
   private subscription?: Subscription;
   state: ReportsState = {
     unreadOrAll: UnreadOrAll.Unread,
@@ -100,21 +107,20 @@ export class Reports extends Component<any, ReportsState> {
     this.subscription = wsSubscribe(this.parseMessage);
 
     // Only fetch the data if coming from another route
-    if (this.isoData.path == this.context.router.route.match.url) {
+    if (this.isoData.path === this.context.router.route.match.url) {
+      const {
+        commentReportsResponse,
+        postReportsResponse,
+        privateMessageReportsResponse,
+      } = this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        listCommentReportsResponse: this.isoData
-          .routeData[0] as ListCommentReportsResponse,
-        listPostReportsResponse: this.isoData
-          .routeData[1] as ListPostReportsResponse,
+        listCommentReportsResponse: commentReportsResponse,
+        listPostReportsResponse: postReportsResponse,
+        listPrivateMessageReportsResponse: privateMessageReportsResponse,
       };
-      if (amAdmin()) {
-        this.state = {
-          ...this.state,
-          listPrivateMessageReportsResponse: this.isoData
-            .routeData[2] as ListPrivateMessageReportsResponse,
-        };
-      }
+
       this.state = {
         ...this.state,
         combined: this.buildCombined(),
@@ -432,73 +438,78 @@ export class Reports extends Component<any, ReportsState> {
     i.refetch();
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let promises: Promise<any>[] = [];
+  static fetchInitialData({
+    auth,
+    client,
+  }: InitialFetchRequest): WithPromiseKeys<ReportsData> {
+    const unresolved_only = true;
+    const page = 1;
+    const limit = fetchLimit;
+
+    const commentReportsForm: ListCommentReports = {
+      unresolved_only,
+      page,
+      limit,
+      auth: auth as string,
+    };
 
-    let unresolved_only = true;
-    let page = 1;
-    let limit = fetchLimit;
-    let auth = req.auth;
+    const postReportsForm: ListPostReports = {
+      unresolved_only,
+      page,
+      limit,
+      auth: auth as string,
+    };
 
-    if (auth) {
-      let commentReportsForm: ListCommentReports = {
-        unresolved_only,
-        page,
-        limit,
-        auth,
-      };
-      promises.push(req.client.listCommentReports(commentReportsForm));
+    const data: WithPromiseKeys<ReportsData> = {
+      commentReportsResponse: client.listCommentReports(commentReportsForm),
+      postReportsResponse: client.listPostReports(postReportsForm),
+    };
 
-      let postReportsForm: ListPostReports = {
+    if (amAdmin()) {
+      const privateMessageReportsForm: ListPrivateMessageReports = {
         unresolved_only,
         page,
         limit,
-        auth,
+        auth: auth as string,
       };
-      promises.push(req.client.listPostReports(postReportsForm));
 
-      if (amAdmin()) {
-        let privateMessageReportsForm: ListPrivateMessageReports = {
-          unresolved_only,
-          page,
-          limit,
-          auth,
-        };
-        promises.push(
-          req.client.listPrivateMessageReports(privateMessageReportsForm)
-        );
-      }
+      data.privateMessageReportsResponse = client.listPrivateMessageReports(
+        privateMessageReportsForm
+      );
     }
 
-    return promises;
+    return data;
   }
 
   refetch() {
-    let unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
-    let page = this.state.page;
-    let limit = fetchLimit;
-    let auth = myAuth();
+    const unresolved_only = this.state.unreadOrAll === UnreadOrAll.Unread;
+    const page = this.state.page;
+    const limit = fetchLimit;
+    const auth = myAuth();
+
     if (auth) {
-      let commentReportsForm: ListCommentReports = {
+      const commentReportsForm: ListCommentReports = {
         unresolved_only,
         page,
         limit,
         auth,
       };
+
       WebSocketService.Instance.send(
         wsClient.listCommentReports(commentReportsForm)
       );
 
-      let postReportsForm: ListPostReports = {
+      const postReportsForm: ListPostReports = {
         unresolved_only,
         page,
         limit,
         auth,
       };
+
       WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm));
 
       if (amAdmin()) {
-        let privateMessageReportsForm: ListPrivateMessageReports = {
+        const privateMessageReportsForm: ListPrivateMessageReports = {
           unresolved_only,
           page,
           limit,
diff --git a/src/shared/components/post/create-post.tsx b/src/shared/components/post/create-post.tsx
index d8a2cce..f43cbb0 100644
--- a/src/shared/components/post/create-post.tsx
+++ b/src/shared/components/post/create-post.tsx
@@ -16,6 +16,7 @@ import { WebSocketService } from "../../services";
 import {
   Choice,
   QueryParams,
+  WithPromiseKeys,
   enableDownvotes,
   enableNsfw,
   getIdFromString,
@@ -36,6 +37,10 @@ export interface CreatePostProps {
   communityId?: number;
 }
 
+interface CreatePostData {
+  communityResponse?: GetCommunityResponse;
+}
+
 function getCreatePostQueryParams() {
   return getQueryParams<CreatePostProps>({
     communityId: getIdFromString,
@@ -52,7 +57,7 @@ export class CreatePost extends Component<
   RouteComponentProps<Record<string, never>>,
   CreatePostState
 > {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<CreatePostData>(this.context);
   private subscription?: Subscription;
   state: CreatePostState = {
     siteRes: this.isoData.site_res,
@@ -71,14 +76,12 @@ export class CreatePost extends Component<
 
     // Only fetch the data if coming from another route
     if (this.isoData.path === this.context.router.route.match.url) {
-      const communityRes = this.isoData.routeData[0] as
-        | GetCommunityResponse
-        | undefined;
+      const { communityResponse } = this.isoData.routeData;
 
-      if (communityRes) {
+      if (communityResponse) {
         const communityChoice: Choice = {
-          label: communityRes.community_view.community.name,
-          value: communityRes.community_view.community.id.toString(),
+          label: communityResponse.community_view.community.name,
+          value: communityResponse.community_view.community.id.toString(),
         };
 
         this.state = {
@@ -206,8 +209,10 @@ export class CreatePost extends Component<
     client,
     query: { communityId },
     auth,
-  }: InitialFetchRequest<QueryParams<CreatePostProps>>): Promise<any>[] {
-    const promises: Promise<any>[] = [];
+  }: InitialFetchRequest<
+    QueryParams<CreatePostProps>
+  >): WithPromiseKeys<CreatePostData> {
+    const data: WithPromiseKeys<CreatePostData> = {};
 
     if (communityId) {
       const form: GetCommunity = {
@@ -215,12 +220,10 @@ export class CreatePost extends Component<
         id: getIdFromString(communityId),
       };
 
-      promises.push(client.getCommunity(form));
-    } else {
-      promises.push(Promise.resolve());
+      data.communityResponse = client.getCommunity(form);
     }
 
-    return promises;
+    return data;
   }
 
   parseMessage(msg: any) {
diff --git a/src/shared/components/post/post.tsx b/src/shared/components/post/post.tsx
index 96d7911..fc8245d 100644
--- a/src/shared/components/post/post.tsx
+++ b/src/shared/components/post/post.tsx
@@ -60,6 +60,7 @@ import {
   toast,
   trendingFetchLimit,
   updatePersonBlock,
+  WithPromiseKeys,
   wsClient,
   wsSubscribe,
 } from "../../utils";
@@ -72,6 +73,11 @@ import { PostListing } from "./post-listing";
 
 const commentsShownInterval = 15;
 
+interface PostData {
+  postResponse: GetPostResponse;
+  commentsResponse: GetCommentsResponse;
+}
+
 interface PostState {
   postId?: number;
   commentId?: number;
@@ -91,7 +97,7 @@ interface PostState {
 
 export class Post extends Component<any, PostState> {
   private subscription?: Subscription;
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<PostData>(this.context);
   private commentScrollDebounced: () => void;
   state: PostState = {
     postId: getIdFromProps(this.props),
@@ -115,11 +121,13 @@ export class Post extends Component<any, PostState> {
     this.state = { ...this.state, commentSectionRef: createRef() };
 
     // Only fetch the data if coming from another route
-    if (this.isoData.path == this.context.router.route.match.url) {
+    if (this.isoData.path === this.context.router.route.match.url) {
+      const { commentsResponse, postResponse } = this.isoData.routeData;
+
       this.state = {
         ...this.state,
-        postRes: this.isoData.routeData[0] as GetPostResponse,
-        commentsRes: this.isoData.routeData[1] as GetCommentsResponse,
+        postRes: postResponse,
+        commentsRes: commentsResponse,
       };
 
       if (this.state.commentsRes) {
@@ -197,19 +205,18 @@ export class Post extends Component<any, PostState> {
     }
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let pathSplit = req.path.split("/");
-    let promises: Promise<any>[] = [];
+  static fetchInitialData(req: InitialFetchRequest): WithPromiseKeys<PostData> {
+    const pathSplit = req.path.split("/");
 
-    let pathType = pathSplit.at(1);
-    let id = pathSplit.at(2) ? Number(pathSplit.at(2)) : undefined;
-    let auth = req.auth;
+    const pathType = pathSplit.at(1);
+    const id = pathSplit.at(2) ? Number(pathSplit.at(2)) : undefined;
+    const auth = req.auth;
 
-    let postForm: GetPost = {
+    const postForm: GetPost = {
       auth,
     };
 
-    let commentsForm: GetComments = {
+    const commentsForm: GetComments = {
       max_depth: commentTreeMaxDepth,
       sort: "Hot",
       type_: "All",
@@ -218,7 +225,7 @@ export class Post extends Component<any, PostState> {
     };
 
     // Set the correct id based on the path type
-    if (pathType == "post") {
+    if (pathType === "post") {
       postForm.id = id;
       commentsForm.post_id = id;
     } else {
@@ -226,10 +233,10 @@ export class Post extends Component<any, PostState> {
       commentsForm.parent_id = id;
     }
 
-    promises.push(req.client.getPost(postForm));
-    promises.push(req.client.getComments(commentsForm));
-
-    return promises;
+    return {
+      postResponse: req.client.getPost(postForm),
+      commentsResponse: req.client.getComments(commentsForm),
+    };
   }
 
   componentWillUnmount() {
diff --git a/src/shared/components/private_message/create-private-message.tsx b/src/shared/components/private_message/create-private-message.tsx
index 327386c..c897c44 100644
--- a/src/shared/components/private_message/create-private-message.tsx
+++ b/src/shared/components/private_message/create-private-message.tsx
@@ -12,6 +12,7 @@ import { i18n } from "../../i18next";
 import { InitialFetchRequest } from "../../interfaces";
 import { WebSocketService } from "../../services";
 import {
+  WithPromiseKeys,
   getRecipientIdFromProps,
   isBrowser,
   myAuth,
@@ -24,6 +25,10 @@ import { HtmlTags } from "../common/html-tags";
 import { Spinner } from "../common/icon";
 import { PrivateMessageForm } from "./private-message-form";
 
+interface CreatePrivateMessageData {
+  recipientDetailsResponse: GetPersonDetailsResponse;
+}
+
 interface CreatePrivateMessageState {
   siteRes: GetSiteResponse;
   recipientDetailsRes?: GetPersonDetailsResponse;
@@ -35,7 +40,7 @@ export class CreatePrivateMessage extends Component<
   any,
   CreatePrivateMessageState
 > {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<CreatePrivateMessageData>(this.context);
   private subscription?: Subscription;
   state: CreatePrivateMessageState = {
     siteRes: this.isoData.site_res,
@@ -52,11 +57,10 @@ export class CreatePrivateMessage extends Component<
     this.subscription = wsSubscribe(this.parseMessage);
 
     // Only fetch the data if coming from another route
-    if (this.isoData.path == this.context.router.route.match.url) {
+    if (this.isoData.path === this.context.router.route.match.url) {
       this.state = {
         ...this.state,
-        recipientDetailsRes: this.isoData
-          .routeData[0] as GetPersonDetailsResponse,
+        recipientDetailsRes: this.isoData.routeData.recipientDetailsResponse,
         loading: false,
       };
     } else {
@@ -74,15 +78,21 @@ export class CreatePrivateMessage extends Component<
     WebSocketService.Instance.send(wsClient.getPersonDetails(form));
   }
 
-  static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
-    let person_id = Number(req.path.split("/").pop());
-    let form: GetPersonDetails = {
+  static fetchInitialData(
+    req: InitialFetchRequest
+  ): WithPromiseKeys<CreatePrivateMessageData> {
+    const person_id = Number(req.path.split("/").pop());
+
+    const form: GetPersonDetails = {
       person_id,
       sort: "New",
       saved_only: false,
       auth: req.auth,
     };
-    return [req.client.getPersonDetails(form)];
+
+    return {
+      recipientDetailsResponse: req.client.getPersonDetails(form),
+    };
   }
 
   get documentTitle(): string {
diff --git a/src/shared/components/search.tsx b/src/shared/components/search.tsx
index 9f76278..c62c7a9 100644
--- a/src/shared/components/search.tsx
+++ b/src/shared/components/search.tsx
@@ -32,6 +32,7 @@ import { WebSocketService } from "../services";
 import {
   Choice,
   QueryParams,
+  WithPromiseKeys,
   capitalizeFirstLetter,
   commentsToFlatNodes,
   communityToChoice,
@@ -80,6 +81,14 @@ interface SearchProps {
   page: number;
 }
 
+interface SearchData {
+  communityResponse?: GetCommunityResponse;
+  listCommunitiesResponse?: ListCommunitiesResponse;
+  creatorDetailsResponse?: GetPersonDetailsResponse;
+  searchResponse?: SearchResponse;
+  resolveObjectResponse?: ResolveObjectResponse;
+}
+
 type FilterType = "creator" | "community";
 
 interface SearchState {
@@ -237,7 +246,7 @@ function getListing(
 }
 
 export class Search extends Component<any, SearchState> {
-  private isoData = setIsoData(this.context);
+  private isoData = setIsoData<SearchData>(this.context);
   private subscription?: Subscription;
   state: SearchState = {
     searchLoading: false,
@@ -271,45 +280,44 @@ export class Search extends Component<any, SearchState> {
 
     // Only fetch the data if coming from another route
     if (this.isoData.path === this.context.router.route.match.url) {
-      const communityRes = this.isoData.routeData[0] as
-        | GetCommunityResponse
-        | undefined;
-      const communitiesRes = this.isoData.routeData[1] as
-        | ListCommunitiesResponse
-        | undefined;
+      const {
+        communityResponse,
+        creatorDetailsResponse,
+        listCommunitiesResponse,
+        resolveObjectResponse,
+        searchResponse,
+      } = this.isoData.routeData;
+
       // This can be single or multiple communities given
-      if (communitiesRes) {
+      if (listCommunitiesResponse) {
         this.state = {
           ...this.state,
-          communities: communitiesRes.communities,
+          communities: listCommunitiesResponse.communities,
         };
       }
-      if (communityRes) {
+      if (communityResponse) {
         this.state = {
           ...this.state,
-          communities: [communityRes.community_view],
+          communities: [communityResponse.community_view],
           communitySearchOptions: [
-            communityToChoice(communityRes.community_view),
+            communityToChoice(communityResponse.community_view),
           ],
         };
       }
 
-      const creatorRes = this.isoData.routeData[2] as GetPersonDetailsResponse;
-
       this.state = {
         ...this.state,
-        creatorDetails: creatorRes,
-        creatorSearchOptions: creatorRes
-          ? [personToChoice(creatorRes.person_view)]
+        creatorDetails: creatorDetailsResponse,
+        creatorSearchOptions: creatorDetailsResponse
+          ? [personToChoice(creatorDetailsResponse.person_view)]
           : [],
       };
 
       if (q !== "") {
         this.state = {
           ...this.state,
-          searchResponse: this.isoData.routeData[3] as SearchResponse,
-          resolveObjectResponse: this.isoData
-            .routeData[4] as ResolveObjectResponse,
+          searchResponse,
+          resolveObjectResponse,
           searchLoading: false,
         };
       } else {
@@ -342,17 +350,21 @@ export class Search extends Component<any, SearchState> {
     client,
     auth,
     query: { communityId, creatorId, q, type, sort, listingType, page },
-  }: InitialFetchRequest<QueryParams<SearchProps>>): Promise<any>[] {
-    const promises: Promise<any>[] = [];
-
+  }: InitialFetchRequest<
+    QueryParams<SearchProps>
+  >): WithPromiseKeys<SearchData> {
     const community_id = getIdFromString(communityId);
+    let communityResponse: Promise<GetCommunityResponse> | undefined =
+      undefined;
+    let listCommunitiesResponse: Promise<ListCommunitiesResponse> | undefined =
+      undefined;
     if (community_id) {
       const getCommunityForm: GetCommunity = {
         id: community_id,
         auth,
       };
-      promises.push(client.getCommunity(getCommunityForm));
-      promises.push(Promise.resolve());
+
+      communityResponse = client.getCommunity(getCommunityForm);
     } else {
       const listCommunitiesForm: ListCommunities = {
         type_: defaultListingType,
@@ -360,23 +372,29 @@ export class Search extends Component<any, SearchState> {
         limit: fetchLimit,
         auth,
       };
-      promises.push(Promise.resolve());
-      promises.push(client.listCommunities(listCommunitiesForm));
+
+      listCommunitiesResponse = client.listCommunities(listCommunitiesForm);
     }
 
     const creator_id = getIdFromString(creatorId);
+    let creatorDetailsResponse: Promise<GetPersonDetailsResponse> | undefined =
+      undefined;
     if (creator_id) {
       const getCreatorForm: GetPersonDetails = {
         person_id: creator_id,
         auth,
       };
-      promises.push(client.getPersonDetails(getCreatorForm));
-    } else {
-      promises.push(Promise.resolve());
+
+      creatorDetailsResponse = client.getPersonDetails(getCreatorForm);
     }
 
     const query = getSearchQueryFromQuery(q);
 
+    let searchResponse: Promise<SearchResponse> | undefined = undefined;
+    let resolveObjectResponse:
+      | Promise<ResolveObjectResponse | undefined>
+      | undefined = undefined;
+
     if (query) {
       const form: SearchForm = {
         q: query,
@@ -391,21 +409,26 @@ export class Search extends Component<any, SearchState> {
       };
 
       if (query !== "") {
-        promises.push(client.search(form));
+        searchResponse = client.search(form);
         if (auth) {
           const resolveObjectForm: ResolveObject = {
             q: query,
             auth,
           };
-          promises.push(client.resolveObject(resolveObjectForm));
+          resolveObjectResponse = client
+            .resolveObject(resolveObjectForm)
+            .catch(() => undefined);
         }
-      } else {
-        promises.push(Promise.resolve());
-        promises.push(Promise.resolve());
       }
     }
 
-    return promises;
+    return {
+      communityResponse,
+      creatorDetailsResponse,
+      listCommunitiesResponse,
+      resolveObjectResponse,
+      searchResponse,
+    };
   }
 
   get documentTitle(): string {
diff --git a/src/shared/interfaces.ts b/src/shared/interfaces.ts
index a6b2ae4..dc4490c 100644
--- a/src/shared/interfaces.ts
+++ b/src/shared/interfaces.ts
@@ -5,15 +5,15 @@ import { ErrorPageData } from "./utils";
 /**
  * This contains serialized data, it needs to be deserialized before use.
  */
-export interface IsoData {
+export interface IsoData<T extends object = any> {
   path: string;
-  routeData: any[];
+  routeData: T;
   site_res: GetSiteResponse;
   errorPageData?: ErrorPageData;
 }
 
-export type IsoDataOptionalSite = Partial<IsoData> &
-  Pick<IsoData, Exclude<keyof IsoData, "site_res">>;
+export type IsoDataOptionalSite<T extends object = any> = Partial<IsoData<T>> &
+  Pick<IsoData<T>, Exclude<keyof IsoData<T>, "site_res">>;
 
 export interface ILemmyConfig {
   wsHost?: string;
diff --git a/src/shared/routes.ts b/src/shared/routes.ts
index b5c2818..81771d0 100644
--- a/src/shared/routes.ts
+++ b/src/shared/routes.ts
@@ -22,13 +22,14 @@ import { Post } from "./components/post/post";
 import { CreatePrivateMessage } from "./components/private_message/create-private-message";
 import { Search } from "./components/search";
 import { InitialFetchRequest } from "./interfaces";
+import { WithPromiseKeys } from "./utils";
 
-interface IRoutePropsWithFetch extends IRouteProps {
+interface IRoutePropsWithFetch<T extends object> extends IRouteProps {
   // TODO Make sure this one is good.
-  fetchInitialData?(req: InitialFetchRequest): Promise<any>[];
+  fetchInitialData?(req: InitialFetchRequest): WithPromiseKeys<T>;
 }
 
-export const routes: IRoutePropsWithFetch[] = [
+export const routes: IRoutePropsWithFetch<Record<string, any>>[] = [
   {
     path: `/`,
     component: Home,
diff --git a/src/shared/utils.ts b/src/shared/utils.ts
index 5648df0..fe83977 100644
--- a/src/shared/utils.ts
+++ b/src/shared/utils.ts
@@ -1262,7 +1262,7 @@ export function isBrowser() {
   return typeof window !== "undefined";
 }
 
-export function setIsoData(context: any): IsoData {
+export function setIsoData<T extends object>(context: any): IsoData<T> {
   // If its the browser, you need to deserialize the data from the window
   if (isBrowser()) {
     return window.isoData;
@@ -1557,6 +1557,10 @@ export type QueryParams<T extends Record<string, any>> = {
   [key in keyof T]?: string;
 };
 
+export type WithPromiseKeys<T extends object> = {
+  [K in keyof T]: Promise<T[K]>;
+};
+
 export function getQueryParams<T extends Record<string, any>>(processors: {
   [K in keyof T]: (param: string) => T[K];
 }): T {
-- 
2.44.1