Solved

Posting frontend shopify node react app form data to backend using node express mongoose

HardikM
Shopify Partner
13 1 5

Hello everyone, I'm new to app development and have developed an app following https://shopify.dev/apps/tools/cli/getting-started as front-end, the ui is working fine and is loading from localhost port 8081 via ngrok to Shopify, have also developed backend using node, express and mongoose, running fine on localhost 3000, but I'm unable to push data from front-end to backend, can someone pl. help at the earliest, I understand Shopify uses https://shopify.dev/apps/online-store/app-proxies but I'm unable to follow the same, my frontend code is as follows

 

import { useState, useCallback } from "react";

import { Button,Card,Form,FormLayout,TextField,} from "@shopify/polaris";
import Router from "koa-router";

const RegForm = () => {
  const [serialNum, setSerialNum] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [errors, setErrors] = useState({});
  const router = Router();

  const fetch = require("node-fetch");

  const handleSubmit = useCallback(
    (e) => {
      e.preventDefault();
      let errs = validate();
      setErrors(errs);
      setIsSubmitting(true);
      async function post_request() {
        const url = "http://localhost:3000/register";
        let platform = "shopify";
        const body = { serialNum, platform };
        console.log(body);
        const res = await fetch(url, {
          method: "POST",
          body: JSON.stringify(body),
          headers: {
            "Content-Type": "application/json",
            'Accept': 'application/json',
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET, POST"
          },
        }).catch((e) => {
          console.log(e);
        });
        const data = await res.json(); //assuming data is json
        console.log(data);
      }
      if (serialNum % 9 === 0) {
        console.log(serialNum);
        alert("Thank You");
        try {
          post_request();
        } catch (error) {
          console.log(error);
        }
      } else {
        alert("Invalid Serial Number");
      }
    },
    [serialNum]
  );

  const handleSerialChange = useCallback((value) => setSerialNum(value), []);

  const breadcrumbs = [{ content: "Registration" }, { content: "next.js" }];
  const primaryAction = { content: "New Registration" };

  const validSerial = !serialNum
    ? "Please Provide Tally Serial Number"
    : serialNum % 9 != 0
    ? "Please Provide Valid Tally Serial Number"
    : "Thank you";

  const validate = () => {
    let err = {};
    if (!serialNum) {
      err.title = "Serial Number is Required";
    } else if (serialNum % 9 != 0) {
      err.title = "Invalid Serial Number";
    } else {
      err.title = "Thank you";
    }
    return err;
  };

  return (
    <Form
      onSubmit={handleSubmit}
      preventDefault={true}
      title="Registration"
      method="POST"
    >
      <FormLayout>
        <Card>
          <Card.Section>
            <TextField
              value={serialNum}
              onChange={handleSerialChange}
              label="Tally Serial Number"
              type="number"
              maxlength={9}
              minlength={9}
              min="700000000"
              max="800000000"
              // helpText="Please Provide Tally Serial Number"
              // error={errors ? ["Please enter a Serial Number"] : null}
            />
          </Card.Section>
        </Card>
        <Card>
          <Card.Section>
            <Button primary={true} fullWidth={true} submit>
              Submit
            </Button>
          </Card.Section>
        </Card>
      </FormLayout>
    </Form>
  );
};

export default RegForm;

 

and my backend code is as follows

 

const express = require("express");

const router = express.Router();

require("../db/conn");
const Registration = require("../models/registrationschema");

router.get("/", (req, res) => {
  res.send("Server Router says Hello");
});

router.get("/register", (req, res) => {
  res.send("just checking");
});

// with async await
router.post("/register", async (req, res) => {
  const { serial, active, store_name, regdate, email } = req.body;

  if (!serial || !active || !email) {
    return res.status(422).json({ error: "Invalid registration details" });
  }

  if (serial % 9 !== 0) {
    return res
      .status(422)
      .json({ error: "Invalid Serial Number, Please Check" });
  }

  try {
    const userExists = await Registration.findOne({
      serial: serial,
      active: true,
    });

    if (userExists) {
      return res.status(422).json({ error: "Serial Already Registered" });
    }
    const register = new Registration({
      serial,
      active,
      store_name,
      regdate,
      email,
    });

    await register.save();

    res.status(201).json({ message: "Serial Registered Successfully" });
  } catch (err) {
    console.log(err);
  }
});

module.exports = router;

 

already tried proxy through package.json, didn't work, please help at the earliest.

Accepted Solution (1)

WarrenWolff
Shopify Partner
14 3 9

This is an accepted solution.

A lot of time has passed since this question has been posted, but I see that there is still no answer. And I hope who passes here will find the solution to their issue!

In Shopify app to perform a fetch request it needs to be authenticated, and Shopify does provide a hook for it.

 

Within the component where you'd like to do so:

import { useAuthenticatedFetch } from '../../hooks';

const appFetch = useAuthenticatedFetch();

await appFetch('/api/init', {
            method: 'POST',
            body: JSON.stringify(data),
            headers: {
                "Content-Type": "application/json",
            }
        })

 

Then, at the backend data will be here:

app.post("/api/init", async (_req, res, ...rest) => {
  console.log(_req.body);

 

Cheers!

View solution in original post

Replies 4 (4)

WebUp
Visitor
1 0 0

Hi I'm facing the same issue can't get data on req.body any news about this thank you.

Gordon_Chan
Shopify Expert
28 2 22

The POST request is missing store session / authorization, so the request shall be 404.

I hit the issue and I am still find the way to fire a post request with the authenciation data like the useAppQuery's GET request.

http://gordon-chan.net
I am a Freelance Web Engineer. Dedicated my life to e-commerce development.
WarrenWolff
Shopify Partner
14 3 9

Hello, check my answer if you are still looking out for a solution, cheers

WarrenWolff
Shopify Partner
14 3 9

This is an accepted solution.

A lot of time has passed since this question has been posted, but I see that there is still no answer. And I hope who passes here will find the solution to their issue!

In Shopify app to perform a fetch request it needs to be authenticated, and Shopify does provide a hook for it.

 

Within the component where you'd like to do so:

import { useAuthenticatedFetch } from '../../hooks';

const appFetch = useAuthenticatedFetch();

await appFetch('/api/init', {
            method: 'POST',
            body: JSON.stringify(data),
            headers: {
                "Content-Type": "application/json",
            }
        })

 

Then, at the backend data will be here:

app.post("/api/init", async (_req, res, ...rest) => {
  console.log(_req.body);

 

Cheers!