Use options to change URL in Nextjs with React-select

Viewed 971

I'm trying to use react-select to change the URL when user select the multiple-options for filter the number. Now, I am facing the problem that when I use multiple-options, it's work to change URL to fetch E.g: https://jsonplaceholder.typicode.com/posts?userId=10&userId=8

When I select single filter, it's also work (userId:1-9). However, it's not work with (userId:10 , value="10")

I know the reason that if I choose single filter, the value will be returned as "string", so when I choose userId:10, it will appear userId:1 (since term[0]=1 rather than 10). If I choose double categories, it will return "Array".

So, how to make the single filter to "Array" rather than "String" in react-select?

*I have 2 ideas to solve the problems(I don't know how to fix):

  1. React-select default Fixed Options to make the string to array
  2. Use qs npm to stringify the URL. However, I don't know how to split the regex with the following: 0=10&1=7&2=3 (I need 10,7,3)
//My filter page
import qs from "qs";
import { useRouter } from "next/router";
import Link from "next/link";
import styles from "../../styles/Home.module.css";

export default function filterPage({ events, term }) {
  const router = useRouter();
  console.log(term);
 
  return (
    <div title="Search Results">
      <Link href="/">Go Back</Link>
      <h1>Search Results for {router.query.term}</h1>

      {events.length === 0 && <h3>No events to show</h3>}
    
      {events.map((evt) => (
        <div className={styles.card}>
          userId: {evt.userId}
          <br />
          {evt.title}
        </div>
      ))}
    </div>
  );
}

// fetch data with qs.npm
export async function getServerSideProps({ query: { term } }) {
  console.log(typeof term);
  console.log(term);

 

  const res = await fetch(
    `https://jsonplaceholder.typicode.com/posts?userId=${term[0]}&userId=${term[1]}&userId=${term[2]}&userId=${term[3]}`
  );

  const events = await res.json();

  return {
    
    props: { events, term },
  };
}
//My Filter component
import Select from "react-select";
import { useState } from "react";
import { useRouter } from "next/router";

const options = [
  { value: "1", label: "UserId:1" },
  { value: "2", label: "UserId:2" },
  { value: "3", label: "UserId:3" },
  { value: "4", label: "UserId:4" },
  { value: "5", label: "UserId:5" },
  { value: "6", label: "UserId:6" },
  { value: "7", label: "UserId:7" },
  { value: "8", label: "UserId:8" },
  { value: "9", label: "UserId:9" },
  { value: "10", label: "UserId:10" },
];



export default function Filter(props) {
  const router = useRouter();
  const [value, setValue] = useState(null);
  const onDropdownChange = (value) => {
    setValue(value);
  };

  const submitSelectCategory = (e) => {
    e.preventDefault();

    const multiCategories = value.map((item) => {
      return item.value;
    });

    const joinURL = multiCategories.join("&term=");
    // const categoriesURL = `/card/${joinURL}`;
    const categoriesURL = `/card/search?term=${joinURL}`;
    router.push(categoriesURL);
  };

  return (
    <div style={{ width: "300px", margin: "30px auto" }}>
      <form onSubmit={submitSelectCategory}>
        <Select
          value={value}
          options={options}
          onChange={onDropdownChange}
          isMulti
          id="long-value-select"
          instanceId="long-value-select"
        />

        <input type="submit" value="Submit" />
      </form>
    </div>
  );
}
1 Answers

Finally, I used es6 if statement to switch the situation between "String" and "Array".

export async function getServerSideProps({ query: { term } }) {
 
// if term = object(array), show term[0]url otherwise, show term
  let arrC =
    term instanceof Object
      ? `https://jsonplaceholder.typicode.com/posts?userId=${term[0]}&userId=${term[1]}&userId=${term[2]}&userId=${term[3]}&userId=${term[4]}&userId=${term[5]}&userId=${term[6]}&userId=${term[7]}&userId=${term[8]}&userId=${term[9]}`
      : `https://jsonplaceholder.typicode.com/posts?userId=${term}`;


  const res = await fetch(arrC);

  const events = await res.json();
  return {
    props: { events, term },
  };
}
Related