Bruno
Bruno

Reputation: 1

How to implement a fetchData function to fetch and filter car data using Sanity?

I am developing an application where I need to fetch car data stored in Sanity and apply filters based on criteria such as price and year. I am having difficulties implementing a fetchData function that can return the correct data within the ranges specified by the user. Problem Description:

Database Structure: I have a data model in Sanity that includes information about cars, such as make, model, year, price, and other characteristics.

Objective: I want to implement a function that:
    Fetches all available cars in Sanity.
    Applies filters for:
        Price: a range defined by the user (e.g., from R$ 20,000 to R$ 50,000).
        Year: a range of years (e.g., from 2010 to 2020).

Usage Example: If the user specifies that they want to see cars priced between R$ 30,000 and R$ 40,000 and from the year 2015 to 2018, the function should return only the cars that meet these criteria.

Sorting Issue: When I apply sorting, I cannot filter the year or price data correctly. This results in a list that does not reflect the filtering criteria I defined.
import { client } from "@/lib/sanity";

interface FilterParams {
  brandCar?: string;
  modelCar?: string;
  location?: string;
  color?: string;
  doors?: number;
  announce?: string;
  minPrice?: number;
  maxPrice?: number;
  bodyType?: string;
  km?: number;
  accessories?: string[];
  startYear?: number;
  endYear?: number;
  motors?: number;
  exchange?: string;
  sortField?: string;
  sortOrder?: "asc" | "desc";
}

export const fetchFilterCars = async ({
  brandCar,
  modelCar,
  location,
  color,
  doors,
  minPrice,
  maxPrice,
  announce,
  bodyType,
  km,
  accessories,
  startYear,
  endYear,
  motors,
  exchange,
  sortField,
  sortOrder,
}: FilterParams) => {
  let query = `*[_type == "car" 
    ${brandCar ? `&& brandCar == $brandCar` : ""}
    ${modelCar ? `&& modelCar match $modelCar` : ""}
    ${location ? `&& location match $location` : ""}
    ${color ? `&& color == $color` : ""}
    ${doors ? `&& doors == $doors` : ""}
    ${announce ? `&& announce == $announce` : ""}
    ${minPrice !== undefined && maxPrice !== undefined ? `&& price >= $minPrice && price <= $maxPrice` : ""}
    ${startYear !== undefined && endYear !== undefined ? `&& yearModification >= $startYear && yearModification <= $endYear` : ""}
    ${motors ? `&& motors == $motors` : ""}
    ${bodyType ? `&& bodyType == $bodyType` : ""}
    ${km ? `&& km == $km` : ""}
    ${
      accessories && accessories.length > 0
        ? accessories
            .map(
              (acc, index) => `&& accessories[$index] match $accessory${index}`,
            )
            .join(" ")
        : ""
    }
  ]`;

  if (sortField && sortOrder) {
    query += ` | order(${sortField} ${sortOrder})`;
  }

  query += `{
    _id,
    brandCar,
    modelCar,
    announce,
    location,
    "imageUrl": images[1].asset->url,
    color,
    price,
    km,
    bodyType,
    accessories,
    yearModification,
    motors,
    exchange
  }`;

  const params: any = {};

  if (brandCar) params.brandCar = brandCar;
  if (modelCar) params.modelCar = `${modelCar}*`;
  if (location) params.location = `${location}*`;
  if (color) params.color = color;
  if (doors) params.doors = doors;
  if (announce) params.announce = announce;
  if (minPrice !== undefined) params.minPrice = minPrice;
  if (maxPrice !== undefined) params.maxPrice = maxPrice;
  if (startYear !== undefined) params.startYear = startYear;
  if (endYear !== undefined) params.endYear = endYear;
  if (motors) params.motors = motors;
  if (bodyType) params.bodyType = bodyType;
  if (km) params.km = km;

  if (accessories && accessories.length > 0) {
    accessories.forEach((accessory, index) => {
      params[`accessory${index}`] = accessory;
    });
  }

  console.log("Generated query:", query);
  console.log("Query parameters:", params);

  try {
    const cars = await client.fetch(query, params);
    return cars;
  } catch (error) {
    console.error("Error fetching cars:", error);
    return [];
  }
};

Questions:

Is this query structure correct?
How can I ensure that the returned data is within the specified price and year ranges, especially when applying sorting?
Is there a more efficient way to perform this filtering with Sanity?

Thank you in advance for your help!

What I Tried and What I Expected:

I implemented the fetchData function to fetch car data from Sanity while applying filters for price and year. I expected that when I provided specific ranges for price (e.g., R$ 30,000 to R$ 40,000) and year (e.g., 2015 to 2018), the function would return only the cars that matched these criteria.

However, when I applied sorting to the results, I noticed that the filtering did not work correctly. Instead of only returning the cars within the specified ranges, the results included cars that were outside of those ranges, which was not the expected behavior.

Upvotes: 0

Views: 36

Answers (0)

Related Questions