I have created a React app that allows users to add images to the cart. Each image is contained in the { cartItems } array which is controlled using Redux. When the user clicks the button, I want a zip file generated with all the images that are in the cart. I think I should be using the jszip library, but can't seem to figure it out. Below is a snippet of my code.
import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import { motion } from 'framer-motion'
import JSZip from 'jszip'
export default function Cart() {
const { cartItems } = useSelector((state) => state.cart)
const handleZipDownload = () => {
}
return (
<div className='pt-16 relative px-12' id='grid-container'>
<h1 className='text-5xl mb-16 text-center' id='grid-header'>
Shopping Cart
</h1>
<button onClick={handleZipDownload}>download images</button>
</div
)
It's doable, I did the same for some .json files.
import JSZip from 'jszip'
import { saveAs } from 'file-saver'
const { cartItems } = useSelector((state) => state.cart)
const handleZipDownload = async () => {
const zip = new JSZip()
cartItems.forEach(img => {
zip.file(img.name, imgData, { base64: true });
})
const zipped = await zip.generateAsync(
{
type: 'blob',
comment: 'Optional comment for example your website URL',
})
saveAs(zipped, 'archive file name')
}
You just need to figure out how to pass imgData depending on how you save/access images in the cart. You most likely have their URLs, in that case use fetch() get the image blob then use it here. If you do end up passing blob as 2nd argument of zip.file then as 3rd argument pass
{ binary: true }
See more
https://stackoverflow.com/a/50248437/8833279
https://stuk.github.io/jszip/documentation/api_jszip/file_data.html
Related
There is similar questions in stackoverflow but none of that fixed my issues... Maybe because that questions are old and the solutions for older versions.... So I tried different methods I saw but none of it helped still showing the same error.. please help me fix it friends...
Create.js file:
import { FirebaseContext, AuthContext } from '../../store/Context';
const { firebase } = useContext(FirebaseContext);
const handleSubmit = () => {
firebase.storage().ref(`/image/${image.name}`).put(image).on('state_changed').then(({ ref }) => {
ref.getDownloadURL().then((url) => {
console.log(url);
})
})
}
return (
<Fragment>
<button className="uploadBtn" onClick={handleSubmit}>Upload and Submit</button>
<Fragment/>
)
I have added only the necessary parts here.
The firebase config file has the following imports:
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
import 'firebase/storage'
I am doing my project in React.
You're importing the compat paths of auth and firestore, which means you can use the namespaced syntax when using those products. But for storage you're importing the default path, meaning you must use the new modular syntax of the SDK version you use.
To be able to use the namespaced syntax for storage too:
import 'firebase/compat/storage'
For Uploading image to firebase storage and get the url for the uploaded image, You can use this:
import { getStorage, ref, uploadBytes,getDownloadURL } from "firebase/storage";
const Create = () => {
const handleSubmit = () => {
const storage = getStorage();
const storageRef = ref(storage, `/image/${image.name}`);
//uploads the file to firebase storage
uploadBytes(storageRef, image).then((snapshot) => {
console.log('Uploaded a blob or file!');
}
).then(() => {
//gets the url for the uploaded image
getDownloadURL(ref(storage, `/image/${image.name}`)).then((url) => {
console.log('url is: ' + url);
})
})
}
return (
<Fragment>
<div>
<button className="uploadBtn" onClick={handleSubmit}>Upload</button>
</div>
</Fragment>
)
}
I'm doing the youtube tutorial "ECommerce Web Shop - Build & Deploy an Amazing App | React.js, Commerce.js, Stripe" and this error appeared when I was sending a new product object from the Commerce.js. (minute 45:50)
I have the corresponding code:
import React, {useState, useEffect } from 'react';
import { commerce } from './lib/commerce'
import {Products, Navbar } from './components'
// to create a full function web shell app, we need a
// full api that is stored on commerce import
const App = () => {
//new state
const [products, setProducts] = useState([]);
// fetch data from the commerce instance
// fetch the products immediatelly on the aplication load
const fetchProducts = async () => {
// this is going to return a promise that we have to
// await to see what is inside of that promise
const { data } = await commerce.products.list();
// now the products are going to be populated
setProducts(data);
}
/* this is to call the fetch product function and set
products to the state, the empty list means that it's
only going to render at the start */
useEffect(() => {
fetchProducts();
},[]);
console.log(products);
return (
<div>
<Navbar/>
<Products/>
</div>
);
}
export default App;
[It should have printed the object on the console, but instead I have the error]
(Error)
https://i.stack.imgur.com/Symbp.png
Hi here is what is working and what i need to change.
I have under my SCR folder a data folder for testing purposes in which there are many json files.
I actually have many react list component which I want to change to only one generic component by passing the json filename and path instead of hardcoding it.
this works
import React from 'react'
import { Link } from 'react-router-dom'
import * as s from '../../components/Shared/ListCards.styles'
import ListData from '../../data/user.json'
const ListCards = () => {
const listJSX = ListData.map((user, index) => {
return ()
I would like to change
import ListData from '../../data/user.json'
to
import ListData from 'path/filename.json'
path and filename is stored in localStorage
localStorage.getItem('colName')
You could use dynamic imports
const { default: ListData } = await import('path/filename.json');
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports
You may want to considering using the fetch api instead, if the path stored inside your local storage relates to a URL:
const ListCards = () => {
const { listData, setListData } = useState([]);
(async () => {
const response = await fetch('/urlpath/filename.json')
const data = await response.json()
setListData(data)
})();
const listJSX = listData.map((user, index) => {
return ()
Im making React app that shows coins' data from API.
I did it with useEffect and it works fine, but now I'm trying to do the same using Mobx.
Im trying to create a store file that gets the data from an API and stores it, then passes it to App.js and then displays the data on screen.
Im new with Mobx. Please help me resolving my Issue
This is my useEffect:
useEffect(() => {
axios.get('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false')
.then(res => {
setCoins(res.data)
console.log(res.data)
}).catch(error => console.log(error))
}, []);
How can I convert this useEffect to Mobx in Store.js file?
For the first step I just want to display coins' name.
Thanks!
The structure should look like this one:
// Coins Store file
type Coin = {
name: string;
}
export class CointStore {
// not sure what is your coins data type, lets assume this is array
readonly coins = observable<Coin>([]);
constructor() {
makeAutoObservable(this);
}
getCoins() {
return axios.get('https://api.coingecko.com/api/v3/coins/markets')
.then(response => this.coins.replace(response.data);
}
}
...
// this is app.js file
import {observer} from 'mobx-react-lite'
import {createContext, useContext, useEffect} from "react"
import {CointStore} from './CointStore'
const CoinsContext = createContext<CointStore>()
const CoinsView = observer(() => {
const coinStore = useContext(CoinsContext);
useEffect(() => {
coinStore.getCoins()
}, []);
return (
<span>
{coinStore.coins.map(coin => <span>{coin.name}</span>)}
</span>
)
})
ReactDOM.render(
<CoinsContext.Provider value={new CointStore()}>
<CoinsView />
</CoinsContext.Provider>,
document.body
)
I have a React component (also using TypeScript) that returns a photo to its parent component:
import React, { useEffect, useState } from "react";
import axios from "axios";
export const Photo = () => {
const [image, setImage] = useState<Image[]>([]);
// Backend API
const proxyUrl = "http://localhost:3001";
const api = "/photo";
interface Image {
src: string;
}
useEffect(() => {
(async function callAPI() {
axios
.get<Image>(proxyUrl + api)
.then((response) => {
setImage([
{
...response.data,
},
]);
})
.catch((error) => console.log(error));
})();
}, []);
if (image.length === 0) return <span>loading Image...</span>;
return <img src={String(image[0])} />;
The goal is to get an artist's profile picture from my backend. The only way that I can save the image in state is by using the spread operator, and when I do so, it SPREADS the URL - placing each taking each letter and placing it as a value in an object (see the screenshot below).
When I remove the spread operator, I get lots of errors. I need a way to retrieve the photo URL without breaking it up so that I can return and view it. Perhaps by changing the way I defined the interface? Or by setting up state differently?
Image of the URL being spread
first of all modify your useState like this :
const [image, setImage] = useState<String>([]);
and data is fetched you should setState like this :
setImage(response.data)
and delete Image from your get function type.
your return :
return <img src={image)} />;
With the help of the comments above by mortezashojaei, I was able to tweak the component and finally able to get it to work as intended. Adding the code here in case anyone's interested.
import React, { useEffect, useState } from "react";
import axios from "axios";
export const Photo = () => {
const [image, setImage] = useState<string>("");
// Backend API
const proxyUrl = "http://localhost:3001";
const api = "/photo";
useEffect(() => {
(async function callAPI() {
axios
.get(proxyUrl + api)
.then((response) => {
setImage(response.data);
console.log("RESPONSE.DATA");
console.log(response.data);
})
.catch((error) => console.log(error));
})();
}, []);
console.log("Image (state): ");
console.log(image);
if (!image) return <span>loading Image...</span>;
return <img src={image} />;
};