javascriptreactjsnext.js

Pass data from server action to server component


i'm trying to pass data in my nextJS14 app from my create server action to my Home server component, specifically the value of the temperature variable so i can display it in the the jsx of my Home server component, how do I do that please.

import Image from "next/image";
import Link from "next/link";
import ProductCard from "./components/ProductCard";
import Search from "./components/Search";

interface latLong {
  latitude: string;
  longitude: string;
}
//server action
export async function create(data: string) {
  console.log(data);
  if (data != "") {
    const apiKey = "123456";
    const geoLocationRes = await fetch(
      `http://api.openweathermap.org/geo/1.0/direct?q=${data}&appid=${apiKey}`
    );
    const geoLocation = await geoLocationRes.json();
    console.log(geoLocation);

    const getLocation: latLong = {
      latitude: geoLocation[0].lat,
      longitude: geoLocation[0].lat,
    };
    const currentWeatherRes = await fetch(
      ` https://api.openweathermap.org/data/2.5/weather?lat=${getLocation.latitude}&lon=${getLocation.longitude}&appid=${apiKey}&units={metric}`
    );
    const currentWeather = await currentWeatherRes.json();
    console.log(currentWeather);

    const temperature = currentWeather.main.temp;
    // console.log(temperature);
    // console.log("input!!");
  } else {
    console.log("no input value");
  }
}
//server component
export default async function Home() {
  return (
    <>
      <h1>Display Temperature here</h1>

      <Search />
    </>
  );
}
const Search = () => {
  const [inputVal, setInputVal] = useState("");

  const OnClick = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    create(inputVal);
  };

  return (
    <>
      <form>
        <input type="text" onChange={(e) => setInputVal(e.target.value)} />
        <button type="button" onClick={OnClick}>
          click
        </button>
      </form>
    </>
  );

Solution

  • Simply call the function within your component, awaiting the value.

    import Image from "next/image";
    import Link from "next/link";
    import ProductCard from "./components/ProductCard";
    import Search from "./components/Search";
    
    interface latLong {
      latitude: string;
      longitude: string;
    }
    //server action
    export async function create(data: string) {
      console.log(data);
      if (data != "") {
        const apiKey = "123456";
        const geoLocationRes = await fetch(
          `http://api.openweathermap.org/geo/1.0/direct?q=${data}&appid=${apiKey}`
        );
        const geoLocation = await geoLocationRes.json();
        console.log(geoLocation);
    
        const getLocation: latLong = {
          latitude: geoLocation[0].lat,
          longitude: geoLocation[0].lat,
        };
        const currentWeatherRes = await fetch(
          ` https://api.openweathermap.org/data/2.5/weather?lat=${getLocation.latitude}&lon=${getLocation.longitude}&appid=${apiKey}&units={metric}`
        );
        const currentWeather = await currentWeatherRes.json();
    
        const temperature = currentWeather.main.temp;
        return temperature;
      } else {
        console.log("no input value");
      }
    }
    //server component
    export default async function Home() {
      // Don't forget to pass in whatever data should go to the server action
      const temp = await create();
      return (
        <>
          <h1>Display Temperature here</h1>
          <p>{temp}</p>
          <Search />
        </>
      );
    }