I am encountering an issue with passing the type of vehicle as a parameter to an API in my React application. The problem arises when attempting to pass the variable "vehicle" to the API endpoint; it receives undefined instead of "carros", "motos", or "caminhoes".
Here is the relevant code from my project:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { Brand } from '../pages/VehicleBrand'
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: 'https://parallelum.com.br/fipe/api/v1',
}),
endpoints: (builder) => ({
getBrand: builder.query<Brand[], string>({
query: (vehicle) => `${vehicle}/marcas`,
}),
}),
})
export const { useGetBrandQuery } = api
export default api
import { PayloadAction, createSlice } from '@reduxjs/toolkit'
export type vehicleState = {
vehicle: string
}
const initialState: vehicleState = {
vehicle: 'carros',
}
const vehicleSlice = createSlice({
name: 'vehicle',
initialState,
reducers: {
change: (state, action: PayloadAction<string>) => {
state.vehicle = action.payload
},
},
})
export const { change } = vehicleSlice.actions
export default vehicleSlice.reducer
import { useParams } from 'react-router-dom'
import MainBox from '../../components/MainBox'
import { useGetBrandQuery } from '../../services/api'
export type Brand = {
codigo: string
nome: string
}
type VehicleParams = {
vehicle: string
}
const VehicleBrand = () => {
const { vehicle } = useParams() as VehicleParams
const { data: brand } = useGetBrandQuery(vehicle!)
return (
<div className="container">
<MainBox
children="Selecione a marca do veículo"
to="/VehicleModel"
selectIsVisible={true}
btnChildren="Buscar"
resultIsVisible={false}
brand={brand}
/>
</div>
)
}
export default VehicleBrand
import { configureStore } from '@reduxjs/toolkit'
import vehicleSlice from './reducers/vehicle'
import api from '../services/api'
export const store = configureStore({
reducer: {
vehicle: vehicleSlice,
[api.reducerPath]: api.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(api.middleware),
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
import { useDispatch } from 'react-redux'
import * as S from './styles'
import { change } from '../../store/reducers/vehicle'
const Header = () => {
const dispatch = useDispatch()
const handleChangeVehicle = (vehicle: string) => {
dispatch(change(vehicle))
}
return (
<S.HeaderDiv>
<S.Container className="container">
<S.Title to="/">ConsultaFipe</S.Title>
<nav>
<ul>
<S.NavLink onClick={() => handleChangeVehicle('carros')}>
Carros
</S.NavLink>
<S.NavLink onClick={() => handleChangeVehicle('motos')}>
Motos
</S.NavLink>
<S.NavLink onClick={() => handleChangeVehicle('caminhoes')}>
Caminhões
</S.NavLink>
</ul>
</nav>
</S.Container>
</S.HeaderDiv>
)
}
export default Header
I have tried debugging the issue but haven't been able to find a solution. Any insights or suggestions would be greatly appreciated.
I need to read the value of "vehicle" in the fetch in the api query. The "GET" will be done like this: "GET: https://parallelum.com.br/fipe/api/v1/carros/marcas" where the value is "car" will receive the value of vehicle.
import { Brand } from '../pages/VehicleBrand'
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: 'https://parallelum.com.br/fipe/api/v1',
}),
endpoints: (builder) => ({
getBrand: builder.query<Brand[], string>({
query: (vehicle) => `${vehicle}/marcas`,
}),
}),
})
export const { useGetBrandQuery } = api
export default api
The console return this error: VM8:6 GET https://parallelum.com.br/fipe/api/v1/undefined/marcas 400 (Bad Request)
This is the routes.tsx file:
import { Routes, Route } from 'react-router-dom'
import Home from './pages/Home'
import VehicleModel from './pages/VehicleModel'
import VehicleYear from './pages/VehicleYear'
import VehicleBrand from './pages/VehicleBrand'
import VehicleInfo from './pages/VehicleInfo'
const PagesRouter = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/VehicleBrand" element={<VehicleBrand />} />
<Route path="/VehicleModel" element={<VehicleModel />} />
<Route path="/VehicleYear" element={<VehicleYear />} />
<Route path="/VehicleInfo" element={<VehicleInfo />} />
</Routes>
)
}
export default PagesRouter
Issue
It appears you have navigation items that set a
vehiclevalue in your Redux store, e.g.state.vehicle.vehiclewhile at the same time theVehicleBrandcomponent is expecting to read avehiclevalue from the route params.The issue is that there aren't any routes that provide any route params and
VehicleBranddoesn't read the currentvehiclevalue from state.Solutions
Navigating to and read
vehiclefrom route parametersUpdate the route definitions to include a
vehiclepath parameter.Update the navigation to include a vehicle value in the target path. This is just an example of passing the target path as a prop to be used as a
Linkcomponent target.Update
VehicleBrandto skip the query ifvehicleparameter value is falsey.Read
vehiclefrom stateSelect the
vehiclevalue from state.