Make generated QR code downloadable on react project - javascript

What I'm trying to do is to generate a QR code based on the Device Id to later download it. I figured out how to generate it, it shows OK on the page, everything is ok but is there any possible way to download it? (the QR image, it's a .png)
import QRCode from 'qrcode.react';
render() {
return (
<QRCode value={this.state.values.deviceId} />
)};
This is what I've done:
This is what I want to do:

I figured out how to do it, here is the code:
import QRCode from 'qrcode.react';
constructor(props) {
super(props);
this.download = this.download.bind(this);
}
componentDidMount(){
this.download()
}
render() {
return (
<div style={{display: "none"}} className="HpQrcode"> // hidden div
<QRCode
value={this.state.values._id}
size={128}
level={'H'}
/>
</div>
<a ref={(ref: any): any => this.downloadRef = ref}>
Download QR Code
</a>
)};
download() {
const canvas: any = document.querySelector('.HpQrcode > canvas');
this.downloadRef.href = canvas.toDataURL();
this.downloadRef.download = this.state.values.deviceId + "-QR.png";
}

Related

Images are disappearing after refreshing the page in React

I am trying to display the data and image using a component.First time the data and images appears but when i refresh the page then data and images both disappear.
This is by component Team.js
import React from 'react';
const Team = (props)=>{
return(
<>
<h1>{props.data.name}</h1>
<img name="photo" src={require(`../images/${props.data.image}`)}/>
</>
)
}
export default Team;
My component is present in components folder and images are present in images folder.
require usually does not work with string literals (template strings). In other words, the location needs to be known at compile time.
I see two solutions.
1. Store your images in the public/images folder, and reference them using your website URL (Preferable)
Lets say you store all your image in the public/images folder. We can get the public url of the website using
var imageBasePath = window.location.protocol + "//" + window.location.host + "/images/";
this will then allow us to use this to reference our public images in the src for an img tag.
<img name="photo" src={imageBasePath + props.data.image} />
where image is the actual name of the image located in the public/images folder.
your team component would look like this
const Team = (props) => {
var imageBasePath =
window.location.protocol + "//" + window.location.host + "/images/";
return (
<>
<h1>{props.data.name}</h1>
<img name="photo" src={imageBasePath + props.data.image} />
</>
);
};
2. Store required images in an array and reference by index, export as an object.
Probably not the preferable method, as working with indexes can be tricky.
export const imageList = [
require("./checklist.jpg"),
require("./question.jpg"),
require("./test-pattern.jpg")
];
and then the Team implementation
import { imageList } from "./Images/imageList";
export const TeamRequire = (props) => {
let image = imageList[props.data.id];
return (
<>
<h1>{props.data.name}</h1>
<img name="photo" src={image} />
</>
);
};
to ease the index issue, we can store and fetch them by objectKey instead
export const imageListObj = {
checkList: require("./checklist.jpg"),
question: require("./question.jpg"),
testPattern: require("./test-pattern.jpg")
};
import { imageListObj } from "./Images/imageList";
export const TeamRequireObj = (props) => {
let image = imageListObj[props.data.imageId];
return (
<>
<h1>{props.data.name}</h1>
<img name="photo" src={image} />
</>
);
};
Here is a codesandbox with the three concepts.
https://codesandbox.io/s/adoring-rosalind-2xhj67?file=/src/App.js

Dynamic loading of images in React JS

I am trying to dynamically get images from my images folder based on some information retrieved from the database. Gone through as many resources as I could but still unable to solve the problem. Here's my code:
import scimitar from "../../images/scimitar.png";
import defender from "../../images/defender.png";
import arrows from "../../images/arrows.png";
import cape from "../../images/cape.png";
import platebody from "../../images/platebody.png";
const ItemCard = ({ item }) => {
return (
<div>
<p key={item.id}>ID: {item.id}</p>
<p>Name: {item.name}</p>
<p>{item.examine}</p>
<p>
<Link to={`/items/${item.id}`}>{item.name}</Link>
</p>
<img src={require(item.name)} alt={item.examine} />
</div>
)
}
const ItemList = () => {
const [items, setItems] = useState(null);
const populateItems = async () => {
const data = await getItems();
setItems(data);
};
useEffect(() => populateItems(), []);
return (
<div>
{items &&
items.map((item, index) => (
<ItemCard item={item} key={index} />
))
}
</div>
)
}
It looks like there are a couple of issues going on. Using template literals like
<img src={`../../images/${item.name}.png`} alt={item.examine} />
won't work either. The reason why is src doesn't take in a path to picture, it looks at a url your website uses. You'll need to setup your React app to serve public images (e.g. make sure something like localhost:1337/images/schimitar.png works).
Only then can you reference it using
<img src={`/images/${item.name}.png` />
To serve static files in create-react-app check out this link. If you have another setup you'll need to use something like babel-plugin-file-loader to serve public assets.
Not sure why this worked but I placed the path of the image in a variable before passing it to the src path of the image tag.
const ItemCard = ({ item }) => {
const imageItem = `/images/${item.name}.png`;
return (
<div>
<p key={item.id}>ID: {item.id}</p>
<p>Name: {item.name}</p>
<p>{item.examine}</p>
<span>Quantity: {item.quantity}</span>
<p>
<Link to={`/items/${item.id}`}>{item.name}</Link>
</p>
<img src={imageItem} alt={item.examine} />
</div>
)
}
export default ItemCard;
<img src={item.name} alt={item.examine} />
Try the following code if you are trying to get the image from a static path.
import image1 from 'images/image1.png';
<img src={image1} alt="image1" />
If you are trying to dynamically add the image then try the following code,
const imgName = "image1.png"
return (
<div>
{ imgName && <img src={`images/${imgName}`} alt="imgName" /> }
</div>
)

ReactJs: Refresh img tag after image update where url remains constant but the image from that url changes

In my app, when user changes image, the url of the image remains the same, but the image in the cloud changes.
In other words, suppose the url of the image is URL1, after the user uploads his image, the image retrieved from that url changes, but the URL remains the same.
The problem with this is that React does not detect the change, and so does not refresh the image tag automatically, and I have to refresh the page, in order to see the new image.
Here's my code:
class ProfilePage extends Component {
saveImageUrlInDatabase(profileImageURL) {
const imageData = {
profileImageURL: profileImageURL,
};
this.props.uploadProfilePictureURL(imageData);
}
async updateAvatar(event) {
const imageFile = event.target.files[0];
if (!imageFile) {
return;
}
const imageURL = await this.props.uploadProfileImage(imageFile);
this.saveImageUrlInDatabase(imageURL);
this.setState({
profileImageURL: imageURL,
});
}
render() {
const { profile, loading } = this.props.profile;
if (!profile || loading) {
profileContent = <Spinner />;
} else {
// #BUG: Even though profileImageSrc changes
// It doesn't get update automatically
// It turns out the url does not change
// But, the image does change
let profileImageSrc;
// True if user has updated his image
if (this.state.profileImageURL !== "") {
profileImageSrc = this.state.profileImageURL;
} else {
profileImageSrc = !profile.profileImageURL
? require("assets/img/faces/lofi-girl.png")
: profile.profileImageURL;
}
profileContent = (
<Container>
<div className="owner">
<div className="avatar">
<Label for="avatar-upload">
<img
alt="..."
className="img-circle img-no-padding img-responsive"
src={profileImageSrc}
key={Math.floor(Math.random() * 10)}
style={{
cursor: "pointer",
}}
title="Change profile image"
/>
</Label>
<input
id="avatar-upload"
type="file"
accept="image/*"
style={{ display: "none" }}
onChange={this.updateAvatar}
/>
</div>
</div>
</Container>
);
}
return <div className="section profile-content">{profileContent}</div>;
}
}
Any idea how to solve this?
I was facing the same problem: I was updating the image in a url but the url was the same. The image didn't update because the brower saved the image in caché. What I'm doing is to add a random number to the end of the url. If the component is different, it will update alone; otherwise, you can add a button to update the random number. Something like:
const [random, setRandom] = React.useState(1)
render
<button onClick={()=>setRandom(Math.random())}>
update image
<button/>
<img
className = 'img-miniatura'
src = {url+'?n='+random}
alt='miniatura'
/>
I think you are not declare to React what your state variables are. Normally you need to define the state as described in the docs of React https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class
You would need to do something like this:
constructor(props) {
super(props);
this.state = {profileImageSrc: //the initial url you want}
}
Your component has some issue, try this:
import fallbackImage from "./assets/img/faces/lofi-girl.png";
class ProfilePage extends Component {
constructor(props) {
super(props)
this.state = {
profileImageURL: props.profile.profileImageURL,
}
}
saveImageUrlInDatabase(profileImageURL) {
const imageData = {
profileImageURL: profileImageURL,
};
this.props.uploadProfilePictureURL(imageData);
}
async updateAvatar(event) {
const imageFile = event.target.files[0];
if (!imageFile) {
return;
}
const imageURL = await this.props.uploadProfileImage(imageFile);
this.saveImageUrlInDatabase(imageURL);
this.setState({
profileImageURL: imageURL,
});
}
render() {
const { profile, loading } = this.props.profile;
const { profileImageURL } = this.state;
return (
<div className="section profile-content">
{!profile || loading && <Spinner />}
<Container>
<div className="owner">
<div className="avatar">
<Label for="avatar-upload">
<img
alt="..."
className="img-circle img-no-padding img-responsive"
src={
profileImageURL ?
profileImageURL :
fallbackImage
}
key={Math.floor(Math.random() * 10)}
style={{
cursor: "pointer",
}}
title="Change profile image"
/>
</Label>
<input
id="avatar-upload"
type="file"
accept="image/*"
style={{ display: "none" }}
onChange={this.updateAvatar}
/>
</div>
</div>
</Container>
</div>
)
}
}

Is there a way I can download a file coming from props, in my react app?

Basically, in my use case, I'm receiving File Object from Parent to the Download component through the props and I want to be able to straight away download it. Is there a way I can do that ?
Please find below reference. [I know, it looks a bit weird in Parent component to select file using file input and to be able to download it just then. This is just for the sake of simplicity.]
Download Button
const DocumentMessage = ({file, type, label, ...props}) => {
return (
<Button as='a' style={{textDecoration: 'none'}} target='_blank' href={file} {...props}>{label}</Button>
);
}
Example of Parent Component where it's used -
export const documentMessageDefault = () => {
const [selectedFile, setSelectedFile] = useState(null);
const handleFileChange = (e) => {
file = e.target.files[0];
setSelectedFile(file);
}
return (
<div>
<input type='file' onChange={handleFileChange} />
<DocumentMessage file={selectedFile} label= 'Download File' />
</div>
);
}

ReactJS - Java Script: Image is not properly showing inside a <div>

I am building a boat visualizer using AISHub and the external database Contentful.
All the vessels I am interested are injected into a table. When I click on the table I locate the marker (vessel) on the map and the image of that vessel pops up on a sidebar on the right of the map as shown below:
The problem I have is that I should also visualize the image of the vessel, but unfortunately I only visualize a weird icon as shown below:
Below the code:
class Sidebar extends React.Component {
state = {
ships: []
};
async componentDidMount() {
let response = await Client.getEntries({
content_type: 'cashmanCards'
});
const ships = response.items.map((item) => {
const { name, slug, type, company, description, images, companylogo } = item.fields;
return {
name,
slug,
type,
company,
description,
images,
companylogo
};
});
this.setState({
ships
});
}
getFilteredShips = () => {
if (!this.props.activeShip) {
return this.state.ships;
}
return this.state.ships.filter((ship) => this.props.activeShip.name.toLowerCase() === ship.name.toLowerCase());
};
render() {
return (
<div className="map-sidebar">
{this.props.activeShipTypes}
<pre>
{this.getFilteredShips().map((ship) => {
console.log(ship);
return (
<Card className="mb-2">
<CardImg />
<CardBody>
<div className="row">
{/* <div className="column"> */}
<img className="image-sizing-primary" src={ship.companylogo} alt="shipImage" />
</div>
<div>
<img className="image-sizing-secondary" src={ship.images} alt="shipImage" />
</div>
<CardTitle>
<h3 className="thick">{ship.name}</h3>
</CardTitle>
<CardSubtitle>{ship.type}</CardSubtitle>
<CardText>
<br />
<h6>Project Details</h6>
<p>For a description of the project view the specification included</p>
</CardText>
<div class="btn-toolbar">
<SpecsButton />
<Link to="/vessels/Atchafalaya" className="btn btn-primary">
Go to vessel
</Link>
</div>
</CardBody>
</Card>
);
})}
</pre>
</div>
);
}
}
export default Sidebar;
What I have done so far:
1) I console.log() the problem that could be the cause of that weird icon and the result (the value) of the command was a strange path. I can confirm that the command is correct. Also I should say that those images are currently held by an external container called Contentful. Below the path after console log:
Am I missing something from the path?
I am not sure how to move on as all other checks seems correct and this one is the only one that is ringing some bells to me.
Thanks for pointing in the right direction for solving this issue.
#Emanuele , could you please try this instead ?
src = {ship.images.fields.file.url}

Categories