Search code examples
next.jsreactstrap

Enter an object and send it to the backend


I have an ECommerce project and this project contains an interface for creating a product, and an interface for creating a product that contains several fields

And these are the fields as they appear in the backend:

mutation{
  createProduct(createProductInput: {
    En:{
      title: "New Product"
      description: "Adding a new Product just for testing"
      tags: ["جديد" ,"اختبار"]
    }

    category: "62b2aef01ae9cf195d385bec"
    collection: "62b2af1a2705c43f5cb64acb"
    brand: "628f20060538cc5b9f58daf5"
   }
}

And as it is clear in the back-end request that there is an Object and there are three fields inside it, title, description, tags "array of strings"

My problem is that I didn't know how to enter the object and the array "Tags"

import { React, useState } from "react";
import {
  Col,
  Button,
  Form,
  FormGroup,
  Label,
  Input,
  FormText,
  Card,
  CardImg,
} from "reactstrap";
import { useCategories } from "../../../../hooks/useCategories";
import { useCollections } from "../../../../hooks/useCollections";
import { useBrand } from "../../../../hooks/useBrand";
import Select from "react-select";

const AddProduct = () => {
  const categories = useCategories();
  const collections = useCollections();
  const brands = useBrand();

  const categoriesOptions = categories?.data?.categories;
  const collectionsOptions = collections?.data?.collections;
  const brandsOptions = brands?.data?.brands;

  const [category, setCategory] = useState(0);
  const [collection, setCollection] = useState(0);
  const [brand, setBrand] = useState(0);

  return (
    <Card
      style={{
        boxShadow: "1px 1px 10px 1px #888888",
        borderRadius: "3rem",
        margin: "5rem",
        padding: "4rem",
      }}
    >
      <Form>
        <h3 style={{ color: "black", fontWeight: "bold" }}>Add Product</h3>

        <div col>
          <img
            width="30%"
            height="40%"
            style={{
              paddingTop: "3rem",
              paddingBottom: "3rem",
              paddingRight: "3rem",
            }}
            src="https://themes.pixelstrap.com/multikart/back-end/assets/images/pro3/34.jpg"
            alt="Card image cap"
          />

          <div>
            <FormGroup row>
              <Label sm={2}>En:</Label>
              <Col sm={10}>
                <Input
                  type="text"
                  name="title"
                  id="title"
                  placeholder="title"
                  
                />

                <Input
                  type="text"
                  name="description"
                  id="description"
                  placeholder="description"
                  style={{ marginTop: '0.7rem', marginBottom: '0.7rem'}}
                />

                <Input type="text" name="tags" id="tags" placeholder="tags" />
              </Col>
             
            </FormGroup>

        <FormGroup row>
          <Label for="exampleSelect" sm={2}>
            Select Collection
          </Label>
          <Col sm={10}>
            <Select
              value={collection}
              // onChange={handleChangeCollection}
              onChange={(collectionsOptions) => {
                console.log("value vvv:", collectionsOptions);
                console.log("value.id: ", collectionsOptions.id);
                setCollection(collectionsOptions.id);
              }}
              options={collectionsOptions}
              getOptionLabel={(e) => e.name}
              getOptionValue={(e) => e.id}
            />
          </Col>
        </FormGroup>

        <FormGroup row>
          <Label for="exampleSelect" sm={2}>
            Select Category
          </Label>
          <Col sm={10}>
            <Select
              value={category}
              onChange={(categoriesOptions) => {
                console.log(
                  "value vvv categoriesOptions:",
                  categoriesOptions
                );
                console.log(
                  "value.id categoriesOptions: ",
                  categoriesOptions.id
                );
                setCategory(categoriesOptions.id);
              }}
              options={categoriesOptions}
              getOptionLabel={(e) => e.name}
              getOptionValue={(e) => e.id}
            />
          </Col>
        </FormGroup>

        <FormGroup row>
          <Label for="exampleSelect" sm={2}>
            Select brands
          </Label>
          <Col sm={10}>
            <Select
              value={brand}
              //onChange={handleChangeCollection}
              onChange={(brandsOptions) => {
                console.log("value vvv:", brandsOptions);
                console.log("value.id: ", brandsOptions.id);
                setBrand(brandsOptions.id);
              }}
              options={brandsOptions}
              getOptionLabel={(e) => e.name}
              getOptionValue={(e) => e.id}
            />
          </Col>
        </FormGroup>
          </div>
        </div>
        <FormGroup check row>
          <Col sm={{ size: 10, offset: 2 }}>
            <Button>Submit</Button>
          </Col>
        </FormGroup>
      </Form>
    </Card>
  );
};

export default AddProduct;

Solution

  • You should create multiple input to handle array value of tags. I've made a simple code

    export default function App() {
      const [tagsLength, setTagsLength] = useState(1);
      const onSubmit = (e) => {
        e.preventDefault();
        const formData = Object.fromEntries(new FormData(e.target));
        const formValue = Object.keys(formData).reduce((acc, cur) => {
          const value = formData[cur];
          if (!cur.includes("tags")) acc[cur] = value;
          else {
            if (!acc["tags"]) acc["tags"] = [value];
            else acc["tags"].push(value);
          }
          return acc;
        }, {});
        console.log(formValue);
      };
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
          <form onSubmit={onSubmit}>
            <input type="text" name="title" id="title" placeholder="title" />
            <input
              type="text"
              name="description"
              id="description"
              placeholder="description"
              style={{ marginTop: "0.7rem", marginBottom: "0.7rem" }}
            />
            {[...Array(tagsLength).keys()].map((i) => (
              <input type="text" name={`tags.${i}`} placeholder="tag name" />
            ))}
            <button onClick={() => setTagsLength(tagsLength + 1)}>Add tag</button>
            <input type="submit" />
          </form>
        </div>
      );
    }
    

    codesandbox. You can see form value in console, hope it help!