Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 5, 2022 07:14 am GMT

Image upload using SolidJS and Cloudinary

In this post we will upload Image from local to cloudinary. We will create useCloudinary hook that will take care of the stuff related to file upload.

Libraries

  • SolidJS
  • Axios
  • SUID
  • Shortid

Features

  • Image preview
  • Upload to Cloudinary
  • Progress bar
  • Abort image upload

src/hooks/useCloudinary.jsx

import axios from "axios";import shortid from "shortid";import { createStore } from "solid-js/store";const url = `https://api.cloudinary.com/v1_1/${  import.meta.env.VITE_CLOUDINARY_CLOUD_NAME}/image/upload`;export default function useCloudinary() {  const [store, setStore] = createStore({    image: null,    imagePreview: "",    uploadProgress: 0,    alert: null,    abortToken: null,  });  function handleImageChange(e) {    const image = e.target.files[0];    // create blob url of selected image for preview    const imagePreview = URL.createObjectURL(image);    // create axios cancellation token to abort request in future    const abortToken = axios.CancelToken.source();    setStore("image", image);    setStore("imagePreview", imagePreview);    setStore("abortToken", abortToken);    setStore("alert", {      severity: "success",      text: "Image loaded successfully",    });  }  function handleImageRemove() {    // cleanup blob  metadata    URL.revokeObjectURL(store.imagePreview);    window.location.reload();  }  async function handleImageUpload() {    try {      const formData = new FormData();      formData.append("file", store.image);      formData.append(        "upload_preset",        import.meta.env.VITE_CLOUDINARY_UPLOAD_PRESET      );      formData.append("api_key", import.meta.env.VITE_CLOUDINARY_API_KEY);      formData.append("public_id", shortid.generate());      const response = await axios.post(url, formData, {        onUploadProgress: handleUploadProgess,        cancelToken: store.abortToken.token,      });      setStore("alert", {        severity: "success",        text: "Image uploaded to cloudinary successfully",      });      // revoke preview blob url      URL.revokeObjectURL(store.imagePreview);      setStore("imagePreview", response.data.url);    } catch (error) {      console.log(error);    }  }  function handleUploadProgess(progressEv) {    const progress = Math.floor((progressEv.loaded / store.image.size) * 100);    console.log(progress);    setStore("uploadProgress", progress);  }  function handleCancelUpload() {    store.abortToken.cancel();    setStore("alert", {      severity: "error",      text: "Image upload aborted",    });  }  return {    store,    handleImageChange,    handleImageRemove,    handleImageUpload,    handleCancelUpload,  };}

we have created a new store and initialise with initial value.

image field will store image selected from local.

imagePreview field will store image url for image preview
and cloudinary url after successfully uploaded.

uploadProgress field will show percentage of image data
uploaded to cloudinary.

alert show success, error and warning message.

abortToken field will store Axios CancelTokenSource which
help to abort request in middle.

handleImageChange() function create blob url of image for
preview and axios cancellation token which we can use in
future to cancel request in middle.

handleImageRemove() method remove preview image and revoke
blob url to clean memory acquired by blob metadata.

handleImageUpload() function upload image to cloudinary
using axios post request and when image successfully
uploaded it revoke blob url and show image from cloudinary
url.

handleUploadProgess() function track uploaded chunk of
image data.

handleCancelUpload() function cancel axios request.

Create .env file in project root and add required environment variable.

.env

VITE_CLOUDINARY_UPLOAD_PRESET=VITE_CLOUDINARY_API_KEY=VITE_CLOUDINARY_CLOUD_NAME=

Prefix with VITE_ is required if you want to access your environment variable in browser.

We will create UI using SUID library. SUID is a Component Material design for Solidjs ported from MUI React.

import { ThemeProvider } from "@suid/material";import Alert from "@suid/material/Alert";import Button from "@suid/material/Button";import Card from "@suid/material/Card";import CardActions from "@suid/material/CardActions";import CardMedia from "@suid/material/CardMedia";import Container from "@suid/material/Container";import Grid from "@suid/material/Grid";import LinearProgress from "@suid/material/LinearProgress";import Stack from "@suid/material/Stack";import { Show } from "solid-js";import useCloudinary from "./hooks/useCloudinary";function App() {  let fileInputRef = null;  const {    store,    handleImageChange,    handleImageRemove,    handleImageUpload,    handleCancelUpload,  } = useCloudinary();  return (    <ThemeProvider>      <Container>        <Grid container sx={{ justifyContent: "center" }}>          <Grid item md={6} xs={12}>            <Show when={store.alert}>              <Alert sx={{ mt: 4, mb: 4 }} severity={store.alert.severity}>                {store.alert.text}              </Alert>            </Show>            <input              type="file"              hidden              ref={fileInputRef}              accept="image/*"              onChange={handleImageChange}            />            <Button              onClick={() => fileInputRef.click()}              variant="contained"              size="large"            >              Select Image            </Button>            <Show when={store.uploadProgress}>              <Stack direction={"column"} spacing={2}>                <LinearProgress                  sx={{ mt: 4 }}                  variant="determinate"                  value={store.uploadProgress}                />                <Button                  variant="contained"                  color="error"                  onClick={handleCancelUpload}                >                  Cancel Upload                </Button>              </Stack>            </Show>            <Show when={store.imagePreview}>              <Card sx={{ mt: 4 }}>                <CardMedia                  component="img"                  height="600px"                  image={store.imagePreview}                  alt="Image Preview"                />                <CardActions>                  <Button                    variant="contained"                    color="error"                    onClick={handleImageRemove}                  >                    Remove                  </Button>                  <Button                    variant="contained"                    color="success"                    onClick={handleImageUpload}                  >                    Upload                  </Button>                </CardActions>              </Card>            </Show>          </Grid>        </Grid>      </Container>    </ThemeProvider>  );}export default App;

GitHub logo harshmangalam / solid-cloudinary-image-upload

Image upload using solidjs and cloudinary

Usage

Those templates dependencies are maintained via pnpm via pnpm up -Lri.

This is the reason you see a pnpm-lock.yaml. That being said, any package manager will work. This file can be safely be removed once you clone a template.

$ npm install # or pnpm install or yarn install

Learn more on the Solid Website and come chat with us on our Discord

Available Scripts

In the project directory, you can run:

npm dev or npm start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

npm run build

Builds the app for production to the dist folder.
It correctly bundles Solid in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

Deployment

You can


Original Link: https://dev.to/kcdchennai/image-upload-using-solidjs-and-cloudinary-634

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To