Home > OS >  how to fetch specific data from API using RTK Query?
how to fetch specific data from API using RTK Query?

Time:12-20

firstly I am new to RTK Query. I am trying to fetch some specific data from API but I don't understand how to do it. If anyone can help me it will be great.

My API link: https://api.spacexdata.com/v3/launches

I just need some specific data like flight_number, mission_name, upcoming, launch_date_utc, rocket_name, launch_success, mission_patch_small .

I already fetched data but can't able to fetch particular data what I want, don't understand how to do it.

My code: App.tsx:

import { useMissionsQuery, useMissionQuery } from "./services/missionsApi";
import "./App.css";

const App = () => {
  const { data, error, isLoading, isFetching, isSuccess } = useMissionsQuery();

  return (
    <div className="App">
      <h1>SpaceX Launches: Mission</h1>
      {isLoading && <h2>...Loading</h2>}
      {isFetching && <h2>...Fetching</h2>}
      {error && <h2>Something went wrong</h2>}
      {isSuccess && (
        <div>
          {data?.map((mission) => {
            return (
              <div className="data" key={mission.flight_number}>
                <span>{mission.mission_name}</span>
                <span>
                  <MissionDetail flight_number={mission.flight_number} />
                </span>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

export const MissionDetail = ({ flight_number }: { flight_number: string }) => {
  const { data } = useMissionQuery(flight_number);
  return <pre>{JSON.stringify(data, undefined, 2)}</pre>;
};

export default App;

services/missionsApi.tsx:

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { Mission } from "../models/mission.model";

export const missionsApi = createApi({
  reducerPath: "missionsApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://api.spacexdata.com/v3/launches",
  }),
  endpoints: (builder) => ({
    missions: builder.query<Mission[], void>({
      query: () => "/",
    }),
    mission: builder.query<Mission, string>({
      query: (flight_number) => `/${flight_number}?`,
    }),
  }),
});

export const { useMissionsQuery, useMissionQuery } = missionsApi;

model mission.model.ts:

export interface Mission {
  flight_number: string;
  mission_name: string;
  upcoming: string;
  launch_date_utc: string;
  rocket: string;
  rocket_name: string;
  launch_success: string;
  links: string;
  mission_patch_small: string;
}

and store.ts

import { configureStore } from "@reduxjs/toolkit";
import { missionsApi } from "./services/missionsApi";

export const store = configureStore({
  reducer: {
    [missionsApi.reducerPath]: missionsApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(missionsApi.middleware),
});

CodePudding user response:

My first thought is the same as @phry -- you are already doing this correctly! You have already fetched all of the data that you need, and you are already displaying individual properties:

<span>{mission.mission_name}</span>

Keep doing that!


Having looked at the API response, you don't actually need to be making any API calls in your MissionDetail component. The list that gets returned from the useMissionsQuery in the App component is giving lots of data about each mission in the list.

You should create a render component that takes the Mission object and displays its information.

function MissionDetail({ mission }: { mission: Mission }) {
  return (
    <div className="data">
      <div>Flight Number: {mission.flight_number}</div>
      <div>Name: {mission.mission_name}</div>
      <div>Launch Date: {mission.launch_date_utc}</div>
    </div>
  );
}

Then your home page can pass each item in the array off to the MissionDetail component to render it. You can simplify your loop to this:

{data?.map((mission) => (
  <MissionDetail key={mission.flight_number} mission={mission} />
))}

(though it seems like flight_number is not a unique key)

You might have other places in your app where you want to render a specific mission by its flight_number, like on a detail page for a mission. That would be where you'd want to call useMissionQuery(flight_number).

function MissionByFlightNumber({ flight_number }: { flight_number: string }) {
  const { data, isError, isLoading, isSuccess } = useMissionQuery(flight_number);
  return (
    <div>
      {isLoading && <h2>...Loading</h2>}
      {isError && <h2>Something went wrong</h2>}
      {isSuccess && data && <MissionDetail mission={data} />}
    </div>
  );
}

Code Sandbox

  • Related