-1

I want to achieve the following

  • FE input a string and press translate button
  • pass the value of that string to the getServerSideProps in the Home (parent) component
  • use that value to call fetchDBData() in order to use the findOne method in MongoDB
  • and I want to present the fetched Data back to FE (Child component)

I could call getchAllDBData() in getServerSideProps and filter the result in the frontend. But

Question: How to pass the value from FE input to inside of getServerSideProps directly? [without through dynamic router]

Data flow

  • press translate button in the child component,
  • pass the input value here(e.g. 11) to getServerSideProps in the parentComponent,
  • getServerSideProps,await fetchDBData(11), and pass it to the props in return
  • getServerSideProps return props to parentComponent
  • parentComponent pass props value to childComponent
  • childComponent renders the received props data

FE layout

Child component


function StartingPageContent({ props, getChild }: any) {
  // Show Link to Login page if NOT auth
  const searchResult = props.data;

  const inputRef = useRef() as any;

  const translate = () => {
        getChild(inputRef.current.value)
 };

return (
    <section>
      <div className="relative inset-0 flex justify-center items-center">
         
        {/* Search Input */}
        <div className="flex flex-col">
          <div className="flex flex-row">
            <div className="flex  mx-8">
              <Input
                placeholder="Input name"
                size="lg"
                type="text"
                id="name"
                ref={inputRef}
              />
              <input />
            </div>

            {/* Search Button*/}
            <div className="flex  mx-8">
              <Button colorScheme="teal" size="lg" onClick={translate}>
                Translate
              </Button>
            </div>
          </div>
          {/* Search Result */}

          <Container className="mt-8" maxW="2xl" bg="gray.100" centerContent>
            <span>From DB</span>
            <Box padding="4" margin="4" bg="gray.300" color="black" maxW="md">
              <span>{searchResult.translation}</span>
            </Box>
          </Container>
        </div>
      </div>
    </section>

}

Parent Component under pages folder

Here is getServerSideProps in index.tsx

export default function Home(props: any) {
  const [childData, setChildData] = useState('')
  function getChild(data: any) {
     setChildData(childData)
  }
  return (
    <main
      className={`flex min-h-screen flex-col items-center justify-between p-24 `}
    >
      <StartingPageContent props={props} getChild={getChild} />
    </main>
  );
}

export async function getServerSideProps() {
  const result = await fetchDBData(PARAM); <==== How to obtain the value of `childData` from Home component
  const data = JSON.parse(JSON.stringify(result));

  if (!data) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  }

  return {
    props: {
      data,
    },
  };
}

Here is the connection to MongoDB

export async function fetchDBData(name: string): Promise<any | undefined> {
  const client = await connectToUserDatabase();
  const userCollection = client.db().collection("target");

  const result = await userCollection.findOne({
    name: name,
  });

  if (!!result) {
    return result;
  }
  return undefined;
}

// Here is the method if I want to filter in the FE
export async function fetchAllDBData(): Promise<any | undefined> {
  const client = await connectToUserDatabase();
  const userCollection = client.db().collection("target");

  const result = await userCollection.find({}).toArray();

  if (!!result) {
    return result;
  }
  return undefined;
}
shawngsg
  • 9
  • 2
  • You can do a client-side navigation to the page with a query param with the string. `getServerSideProps` will fire, and you can retrieve the query from the `context` object. See [docs](https://nextjs.org/docs/pages/api-reference/functions/get-server-side-props#context-parameter) for reference on the context parameter. – ivanatias Aug 10 '23 at 04:51

1 Answers1

0

The solution is by passing your input value to the url so that the getServerSideProps fire inside that you can get the url parameters Try the following

Parent Page

import StartingPageContent from '@components/test';

export default function Home(props: any) {
    return (
        <main className={`flex min-h-screen flex-col items-center justify-between p-24 `}>
            <StartingPageContent props={props} />
        </main>
    );
}

export async function getServerSideProps(context) {
    // you will get the url params in here (context.query.q) if available
    const result = await fetchDBData(context.query.q ?? '');
    const data = JSON.parse(JSON.stringify(result));

    if (!data) {
        return {
            redirect: {
                destination: '/',
                permanent: false,
            },
        };
    }

    return {
        props: {
            data,
        },
    };
}

Child Component

function StartingPageContent({ props }: any) {
  const { push } = useRouter();
    const searchResult = props.data;

    const [input, setInput] = useState('');

    const translate = () => {
        // change router with useRouter from next/router
        push(`/<YOUR_PAGE_NAME>?q=${input}`);
    };

return (
    <section>
      <div className="relative inset-0 flex justify-center items-center">
         
        {/* Search Input */}
        <div className="flex flex-col">
          <div className="flex flex-row">
            <div className="flex  mx-8">
               <Input placeholder="Input name" type="text" id="name" onChange={e => setInput(() => e.target.value)} />
            </div>

            {/* Search Button*/}
            <div className="flex  mx-8">
              <Button colorScheme="teal" size="lg" onClick={translate}>
                Translate
              </Button>
            </div>
          </div>
          {/* Search Result */}

          <Container className="mt-8" maxW="2xl" bg="gray.100" centerContent>
            <span>From DB</span>
            <Box padding="4" margin="4" bg="gray.300" color="black" maxW="md">
              <span>{searchResult.translation}</span>
            </Box>
          </Container>
        </div>
      </div>
    </section>

}