Search code examples
javascriptaxiosnext.jsformikswr

SWR fetch data based on selected value in dropdown


is it possible in swr to fetch data based on the selected value in a dropdown? At first fetch it is working but when I select the previous selected value it won't fetch the correct data.

  1. Fetch API
   const { data: entities } = useSWR(
       currentEntity?.entity_id
         ? "/api/entities/" + currentEntity?.entity_id
         : null,
       { dedupingInterval: 12000 }
     );
  1. This is how I render the data when return
     {!isEmptyObject(individual) &&
                  isTabThree &&
                  selectedEntity === "" ? (
                    <div className="flex items-center justify-center h-48 text-gray-500">
                      Please choose an entity
                    </div>
                  ) : !entities ? (
                    <div className="flex items-center justify-center h-48">
                      <ThreeDotsSpinner />
                    </div>
                  ) : (
                    <EntityForm data={entities} />
                  )}
  1. This is the entity form where data will be store in input the desired behavior is that whenever dropdown changes the form also changes to its correct data thru fetch api
    export default function EntityForm({ data }) {
    
      
      const formik = useFormik({
        initialValues: {
          company_name: data?.company_name ?? "",
          company_type: data?.company_type ?? "",
          company_industry: data?.company_industry ?? "",
          company_address: {
            addresss_line1: data?.company_address?.addresss_line1 ?? "",
            addresss_line2: data?.company_address?.addresss_line2 ?? "",
            city: data?.company_address?.city ?? "",
            province: data?.company_address?.province ?? "",
          },
          company_operations: data?.company_operations ?? "",
          company_monthly_income: data?.company_monthly_income ?? "",
          company_sss: data?.company_sss ?? "",
          company_website: data?.company_website ?? "",
          company_tin: data?.company_tin ?? "",
          company_contact_number: data?.company_contact_number ?? "",
          representative_first_name: data?.representative_first_name ?? "",
          representative_last_name: data?.representative_last_name ?? "",
          representative_position: data?.representative_position ?? "",
          representative_contact_number: data?.representative_contact_number ?? "",
          representative_email: data?.representative_email ?? "",
          representative_employed_duration:
            data?.representative_employed_duration ?? "",
          documents: [],
        },
      });
      return (
        <FormikProvider value={formik}>
          <Form>
            <>
              <header className="absolute right-0 top-40">
                <nav className="mr-6">
                  <Link href="/admin/customers">
                    <a className="text-sm text-gray-500 mr-9">Back</a>
                  </Link>
                  <Button type="submit" className="btn-primary">
                    Update
                  </Button>
                </nav>
              </header>
              <div>
                <h3 className="my-4 text-xs text-gray-400">
                  Applicable if you want to apply loan using your business.
                </h3>
    
                <main className="space-y-10">
                  <section>
                    <h2 className="mb-9">Business Information</h2>
    
                    <div className="grid gap-y-7">
                      <div className="grid grid-cols-3 gap-x-7">
                        <Input
                          label="Business Name"
                          name="company_name"
                          placeholder="Tom Tech"
                        />
                        <div>
                          <ListBox
                            label="Type of Business"
                            options={typeOfBusiness}
                            value={formik.values.company_type}
                            name="company_type"
                            placeholder="Sole Proprieter"
                          />
                        </div>
                        <div>
                          <ListBox
                            label="Type of Business"
                            options={industryData}
                            value={formik.values.company_industry}
                            name="company_industry"
                            placeholder="Tech"
                          />
                        </div>
                      </div>
    
                      <div className="grid grid-cols-2 gap-7">
                        <Input
                          label="Address Line 1"
                          name="company_address.addresss_line1"
                          placeholder="123 Kanto St."
                        />
                        <Input
                          label="Address Line 2"
                          name="company_address.addresss_line2"
                          placeholder="123 Kanto St."
                        />
                        <div>
                          <ListBox
                            label="City/Municipality"
                            options={cityData}
                            value={formik.values.company_address.city}
                            name="company_address.city"
                            placeholder="Manila"
                          />
                        </div>
                        <div>
                          <ListBox
                            label="City/Municipality"
                            options={provinceData}
                            value={formik.values.company_address.province}
                            name="company_address.province"
                            placeholder="Metro Manila"
                          />
                        </div>
                      </div>
    
                      <div className="grid grid-cols-3 gap-7">
                        <Input
                          label="Years of Operation"
                          type="number"
                          name="company_operations"
                          placeholder="20 Years"
                        />
                        <Input
                          label="Average Monthly Income"
                          type="number"
                          name="company_monthly_income"
                          placeholder="Php 50,000"
                        />
                        <Input
                          label="Company Website"
                          name="company_website"
                          placeholder="https://tom.tech"
                        />
                        <Input
                          label="Company SSS"
                          name="company_sss"
                          placeholder="000-123-234-345"
                        />
                        <Input
                          label="Company TIN"
                          name="company_tin"
                          placeholder="06-98723452"
                        />
                        <Input
                          label="Company Tel. No."
                          name="company_contact_number"
                          placeholder="749-8463"
                        />
                      </div>
                    </div>
                  </section>
    
                  <section>
                    <h2 className="mb-9">Representative Details</h2>
    
                    <div className="grid grid-cols-3 gap-7">
                      <Input
                        label="First Name"
                        name="representative_first_name"
                        placeholder="Tom"
                      />
                      <Input
                        label="Last Name"
                        name="representative_last_name"
                        placeholder="Doe"
                      />
    
                      <Input
                        label="Position"
                        name="representative_position"
                        placeholder="Proprietor"
                      />
                      <Input
                        label="Contact Number"
                        name="representative_contact_number"
                        placeholder="Proprietor"
                      />
                      <Input
                        label="Email"
                        type="email"
                        name="representative_email"
                        placeholder="[email protected]"
                      />
    
                      <Input
                        label="Years Employed"
                        type="number"
                        name="representative_employed_duration"
                        placeholder="20 Years"
                      />
                    </div>
                  </section>
    
                  <section>
                    <h2 className="mb-9">Required Documents</h2>
    
                    <div className="grid grid-cols-4">
                      <div className="col-span-1 ml-6 ">
                        <ul className="text-sm list-disc">
                          <li>Company ID (Front & Back)</li>
                          <li>Latest Proof of Billing</li>
                          <li>Company Profile</li>
                          <li>SEC Registration</li>
                          <li>Business/Mayor’s Permit/BIR</li>
                          <li>3 Months latest bank statement</li>
                          <li>2 Valid ID of Representative</li>
                          <li>2 to 3 years In-house financial statement</li>
                          <li>2 to 3 years Audited financial statement</li>
                          <li>List of Cusotmers and Suppliers</li>
                          <li>List of Receivables and Payables</li>
                        </ul>
                      </div>
                      <div className="col-span-3">
                        <FilesDragAndDrop name="documents" />
                      </div>
                    </div>
                  </section>
    
                  {/* FILES PREVIEW */}
                  <section>
                    <FileTable tableHeader={tableHeaders}>
                      {/* {fileData.length > 0 ? (
                        fileData.map(({ file_name, size }, index) => (
                          <tr key={index}>
                            <SingleFileUploadCard
                              file_name={file_name}
                              size={size}
                            />
                          </tr>
                        ))
                      ) : (
                        <tr>
                          <td>Add Required Documents</td>
                        </tr>
                      )} */}
                    </FileTable>
                  </section>
                </main>
              </div>
            </>
          </Form>
        </FormikProvider>
      );
    }

  1. This is the dropdown from headlessui that I've been using recently
import { Fragment, useState } from "react";
import { Listbox, Transition } from "@headlessui/react";
import { CheckIcon, ChevronIcon } from "../ui/icons";

export default function ListBox({
  options,
  value,
  setValue,
  label,
  error,
  placeholder,
}) {
  return (
    <Listbox
      as="div"
      value={value}
      onChange={(val) => {
        setValue(val);
      }}
    >
      <div className="relative">
        <Listbox.Label className="label" htmlFor={label}>
          {label}
        </Listbox.Label>

        <Listbox.Button
          className={`relative w-full form-control 
           ${error && "error"} `}
        >
          <div className="flex items-center">
            <span
              className={`block truncate ${
                value ? "" : "text-base text-gray-400"
              } `}
            >
              {value || value.title || placeholder}
            </span>
          </div>
          <span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
            <ChevronIcon aria-hidden="true" />
          </span>
        </Listbox.Button>
        <Transition
          as={Fragment}
          leave="transition ease-in duration-100"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <Listbox.Options className="absolute z-10 w-full py-1 mt-1 overflow-auto text-base bg-white rounded-md shadow-lg max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
            {options.map((item, index) => (
              <Listbox.Option
                key={index}
                className={({ active }) =>
                  `${active ? "text-forgot bg-green-100" : "text-gray-900"}
                              cursor-default select-none relative py-2 pl-10 pr-4`
                }
                value={item.title}
              >
                {({ selected, active }) => (
                  <>
                    <span
                      className={`${
                        selected && value ? "font-medium" : "font-normal"
                      } block truncate`}
                    >
                      {item.title}
                    </span>
                    {selected && value ? (
                      <span
                        className={`${active ? "text-forgot" : "text-forgot"}
                                    absolute inset-y-0 left-0 flex items-center pl-3`}
                      >
                        <CheckIcon className="w-5 h-5" aria-hidden="true" />
                      </span>
                    ) : null}
                  </>
                )}
              </Listbox.Option>
            ))}
          </Listbox.Options>
        </Transition>
      </div>
    </Listbox>
  );
}
  1. This is api of a current customer with all the data including the entities, I can get the id thru the router query and also this is where I get the currentEntity
const { data: customer } = useSWR(
        id
          ? "/api/customer/" + id
          : null
      );
  1. How I get the currentEntity being selected. The selectedEntity is a state where I store which is being selected by the Listbox which is the dropdown.
const currentEntity = customer?.summary?.type_entities?.find((val) => val.entity_name === selectedEntity)

I hope I explained it clearly ⊙﹏⊙ Badly need ur help, I am also new with these things and still learning some stuff. Your help is greatly appreciated! Thank you.


Solution

  • Problem solved but I don't know if it's the best approach. I just added my formik form with enableReinitialize to update the initial values if the dropdown value changes.