skip to Main Content

I have a problem with this component in next js, if I do the npm run dev it works, the problem is when I try to generate the next js build, it returns this error

./pages/marcas/[marca].tsx:66:30
Type error: 'carData' is possibly 'undefined'.
> 66 |                             {carData.cars && carData.cars.length > 0 ? (
     |                              ^

The code of the component is this

import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Header from '@/app/components/template/Header';
import Footer from '@/app/components/template/Footer';
import Content from '@/app/components/template/Content';
import '../../app/styles/globals.css';
import Link from 'next/link';
import { CarData } from '@/app/types/types';

const capitalizeWords = (str: string) => {
    return str.replace(/bw/g, (char) => char.toUpperCase());
};

const MarcaDetailPage = () => {
    const router = useRouter();
    const { marca } = router.query;
    const [carData, setCarData] = useState<CarData>();
    const [isLoading, setIsLoading] = useState(true);

    useEffect(() => {
        const fetchCarData = async () => {
            try {
                const response = await fetch(
                    `http://localhost:8000/api/cars/brand/${marca}`
                );
                const data = await response.json();
                setCarData(data);
                setIsLoading(false);
            } catch (error) {
                console.error('Error fetching car data:', error);
                setIsLoading(false);
            }
        };

        if (marca) {
            fetchCarData();
        }
    }, [marca]);


    return (
        <>
            <Header />

            <Content>
                {isLoading ? (
                    <div>Loading...</div>
                ) : (
                    <div className="container mx-auto py-8">
                        <h1>Cars {brand}</h1>
                        <div className="grid grid-cols-1">
                            {carData.cars && carData.cars.length > 0 ? (
                                carData.cars.map((car) => (
                                    <div key={car.id} className="p-4 border">
                                    
                                        <p className="mt-4 text-lg font-semibold">
                                            Modelo: {car.model}
                                        </p>
      
                                    </div>
                                ))
                            ) : (
                                <div>Error</div>
                            )}
                        </div>
                    </div>
                )}
            </Content>

            <Footer />
        </>
    );
};

export default MarcaDetailPage;

I’m trying to use the carData interface to obtain an array of objects from the API and display them one by one. I think the error is in the map when I try to use the carData interface but I can’t solve it

CarData Interface



export interface CarData {
    id: number;
    model: string;
    battery_kw: number;
    brand: {
        name: string;
        slug: string;
    };
    year_ini: number;
    year_end: number | null;
    power: number;
    sku_vehicle: string;
    initial_price: number;
    car_images: { id: number; ruta_imagen: string }[];
}

I have searched for help in google, stackoverflow, even chatGPT but I can’t see the solution

2

Answers


  1. In useState() code you are not setting an initial state for carData, so it is undefined until fetch() resolves – hence the error during the build.

    You can change the code to carData?.cars to specify that carData could be undefined (and cars array could not exists too).

    Login or Signup to reply.
  2. const [carData, setCarData] = useState<CarData>();
    

    This () means that the initial value of carData is undefined. You can either initialize it with a value (in case the data was an array) or you can use optional chaining carData?.cars

    {carData?.cars && carData?.cars.length > 0 ? (
      carData.cars.map((car) => (
          <div key={car.id} className="p-4 border">
          
              <p className="mt-4 text-lg font-semibold">
                  Modelo: {car.model}
              </p>
    
          </div>
      ))
    ) : (
      <div>Error</div>
    )}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search