sylargaf
sylargaf

Reputation: 528

NextJS calling API in a form submit

using NextJS i'm having a hell of a time trying to figure out how to get the app to actually call a API I have set up upon form submit. Right now I get a very random error when I hit submit,

Error: Search(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

Which as you can presume ultimately is useless and helps 0. I don't understand why its not working though, as it works in other components elsewhere. Thank you for your help. Here is my code:

api.js


const API = process.env.WP_API_URL;

async function fetchAPI(query, { variables } = {}) {
  const headers = { 'Content-Type': 'application/json' };

  const res = await fetch(API, {
    body: JSON.stringify({ query, variables }),
    headers,
    method: 'POST',
  });

  const json = await res.json();
  if (json.errors) {
    console.log(json.errors);
    console.log('error details:', query, variables);
    throw new Error('Failed to fetch API');
  }

  return json.data;

export async function getCampgroundsByCity(query) {
  const data = await fetchAPI(
    `
    query MyQuery($string: String) {
      campgrounds(where: {city: $string}) {
        nodes {
          acfDetails {
            address
            city
            closeDate
            latitude
            longitude
            numberOfSites
            openDate
            website
            picture {
              altText
              mediaItemUrl
            }
          }
          title
        }
      }
    }
    `,
    {
      variables: {
        string: query,
      },
    }
  );
  return data?.campgrounds;
}

}


newsearch.js:

import { useRouter } from 'next/router';
import { useState } from 'react';
import { ViewportContextProvider } from '../lib/state';
import { getCampgroundsByCity } from '../lib/api';

export default function Search({ viewport, setViewport, cities }) {
  const [view, setView] = useState();

  const handleChange = e => {
    setView(e.target.value);
  };

  const updateViewport = async event => {
    event.preventDefault();

    // const campgroundsbycity = await getCampgroundsByCity('Bethlehem');
    // console.log(view);
  };
  return (
    <form onSubmit={updateViewport}>
      <label htmlFor="city">City</label>
      <select value={view} onChange={handleChange}>
        {cities.nodes.map(town => {
          return (
            <option value={town.acfDetails.city}>{town.acfDetails.city}</option>
          );
        })}
      </select>
      <button type="submit">Submit</button>
    </form>
  );
}

Upvotes: 3

Views: 8564

Answers (1)

Paulo Carvalho
Paulo Carvalho

Reputation: 81

Next.js works in different ways depending on how you structure your code (see this https://nextjs.org/docs/basic-features/data-fetching ). Because of this, different .env variables might be exposed or not. If you need a .env to be public exposed (like the URL from your API call), you will have to use "NEXT_PUBLIC_" on the name, like this "NEXT_PUBLIC_WP_API_URL".

You can read more about it here: https://nextjs.org/docs/basic-features/environment-variables

So, you'll have to change the .env like this:

# OLD
# WP_API_URL=https://my.url.com

# NEW
NEXT_PUBLIC_WP_API_URL=https://my.url.com

And your api.js like this:

// const API = process.env.WP_API_URL;
const API = process.env.NEXT_PUBLIC_WP_API_URL;

Upvotes: 1

Related Questions