Next.js Discord

Discord Forum

Server Action to make a POST Request to Google Cloud Function

Unanswered
Bombay posted this in #help-forum
Open in Discord
BombayOP
New to Server Actions and NextJS.

Problem:
I need so make a basic form with:
- Name:string
- Mail:string
and on submit make a POST request to trigger a Google Cloud Function.

Note:
I want to use server actions and maybe shadcn ui.
I understood the need to make a seperate server component.


Action:
"use server";

export async function CloudFunction(formData: FormData) {
  const name = formData.get("name");
  const email = formData.get("email");
  const response = await fetch(
    "<....url cloud function...>",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ name, email }),
    }
  );
  const result = await response.json();
  console.log(result);
  return result;
}


Component Form:
"use client";

import { useState } from "react";
import { z } from "zod";
import { CloudFunction } from "../actions/CloudFunction";

const schema = z.object({
  name: z.string(),
  email: z.string().email(),
});

export const FormData = () => {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [errors, setErrors] = useState([]);

  return (
    <form action={CloudFunction}>
      <div>
        <label htmlFor="name">Name:</label>
        <input
          type="text"
          id="name"
          value={name}
          onChange={(event) => setName(event.target.value)}
        />
      </div>
      <div>
        <label htmlFor="email">Email:</label>
        <input
          type="email"
          id="email"
          value={email}
          onChange={(event) => setEmail(event.target.value)}
        />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};


I know both are wrong but at leas you have an idea of how bad i am on this 😄

Final Goal:
Form with mail and name -> Send Data to Cloud Function -> Cloud Function return a Json to be displayed in the UI.

Please Help :lolsob:

9 Replies

American Crow
I'd approach it like this inside your client component. No Form Action just a onsubmit handler:
  function onSubmit(data: Inputs) {
    startTransition(async () => {
      const response = await fetch("/api/email/newsletter", {
        method: "POST",
        body: JSON.stringify({
          email: data.email,
          // This token is used as a search param in the email preferences page to identify the subscriber.
          token: crypto.randomUUID(),
          subject: "Welcome to Skateshop13",
        }),
      })

      if (!response.ok) {
        switch (response.status) {
...

and fetch your cloud function isteand of /api/email/newsletter.
I am not a pro though
American Crow
it's the same as a server action just in one file
@Bombay Thank you for the help. I have used like you suggested the onSubmit but also made a sort of server action by calling it on the onsubmit. Not sure if this is purely a server action so i am still hoping to improve.
BombayOP
"use server";

export default async function CloudFunction(formData: FormData) {
  console.log(formData);
  const response = await fetch(
    "https://....cf",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(formData),
    }
  );
  const result = await response.json();
  console.log(result);
  return result;
}
American Crow
wait no it isnt
ther is no "use server"
my approach is just a client side call to the api so the url might be exposed of your endpoint might want ot check that
@American Crow my approach is just a client side call to the api so the url might be exposed of your endpoint might want ot check that
BombayOP
Right, in my case i do no think it is.
In any case is crazy how poor are the references for such common case ...
American Crow
yours is not yea its a server action