1

I am making a form that contains a couple text inputs and one file upload input. I am uncertain how to set the state reflecting an array of what photos have been uploaded. And then how to use the value of said state to make a POST request. In theory, I want to be able to upload a few photos, capture the value of these and set it as the files state and then post the array of info to the endpoint.

function NewItem(props) {


const history = useHistory();
  const { classes } = props;
  const { isDarkMode } = useContext(ThemeContext);
  const { token } = useContext(LoggedInContext);

  const [itemNameValue, handleItemNameChange, resetItemName] = InputState("");
  const [itemPriceValue, handlePriceChange, resetPriceUrl] = InputState("");
  const [
    itemDescriptionValue,
    handleItemDescriptionChange,
    resetItemDescription
  ] = InputState("");

  const [fileState, setFileState] = useState([]);

  const handleFileUpload = e => {
    setFileState(e.target.files[0]);
  };

  const handleNewItemSubmit = e => {
    e.preventDefault();
    fetch("http://localhost:8181/items", {
      body: JSON.stringify({
        title: itemNameValue,
        price: itemPriceValue,
        description: itemDescriptionValue,
        photos: fileState
      }),
      headers: {
        "Content-Type": "application/json",
        Token: token
      },
      method: "POST"
    })
      .then(res => res.json())
      .then(data => {
        console.log(data);
        handleSnackbarClick();
      });
  };
  return (
    <PageContent>
      <Navbar />
      <h1 className={classes.heading} style={{ color: isDarkMode && "white" }}>
        New Item
      </h1>
      <form
        className={classes.newForm}
        noValidate
        autoComplete="off"
        onSubmit={handleNewItemSubmit}
      >

        <TextField
          id="outlined-desc"
          label="Facebook Item Description"
          variant="outlined"
          multiline={true}
          rows={4}
          rowsMax={8}
          onChange={handleItemDescriptionChange}
          value={itemDescriptionValue}
          InputLabelProps={{
            classes: {
              root: isDarkMode && classes.cssLabel,
              focused: classes.cssFocused
            }
          }}
          InputProps={{
            classes: {
              root: isDarkMode && classes.cssOutlinedInput,
              focused: classes.cssFocused,
              notchedOutline: isDarkMode && classes.notchedOutline,
              input: isDarkMode && classes.multilineColor
            }
          }}
        />
        <div className={classes.photo_groups}>
          <input
            accept="image/*"
            className={classes.input}
            style={{ display: "none" }}
            id="raised-button-file"
            multiple
            type="file"
            onChange={handleFileUpload}
          />
          <label htmlFor="raised-button-file">
            <Button
              variant="raised"
              component="span"
              className={classes.button}
            >
              Photo Upload
            </Button>
          </label>
          <GroupCheckbox />
        </div>
      </form>
    </PageContent>
  );
}

1 Answer 1

1

You may use FileReader() to convert the images into base64 strings and send them in the 'POST' data.

Change your handleFileUpload function to this -

const handleFileUpload = e => {
    const reader = new FileReader();
    const file = e.target.files[0];
    reader.onloadend = () => {
      setFileState(reader.result);
    };
    reader.readAsDataURL(file);
  };

reader.readAsDataURL reads the contents of your image file and triggers loadend after it is done.

reader.onloadend function will set fileState as a base64 string.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.