Fallback for Next JS Image component - reactjs

In Next JS Image component for using images from external URL we've to specify the base URL in next.config.js but what if the external urls are dynamic i.e., we don't know from where the images are coming from, then how do I tackle this case?

you must use custom loaders for that
next js document
import Image from 'next/image'
const myLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
const MyImage = (props) => {
return (
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}

Related

How to export a component to a PDF file, that is not visible on UI, but has to be in PDF document (html-to-image, jsPDF, React)

Like the title says, I want to export a component to a PDF file, that I want to be invisible in the app or should I say on UI, but I want it to be inside a PDF document.
To make this PDF exporting functionality I have used the combination of html-to-image library, jsPDF library and everything is made using React.
This is my code:
function App() {
const [exporting, setExporting] = useState(false);
async function createPdf({ doc, element }) {
const imgData = await toPng(element);
const imgProps = doc.getImageProperties(imgData);
const pdfWidth = doc.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(imgData, "PNG", 10, 0, pdfWidth, pdfHeight, "", "FAST");
}
async function handleDownloadPdf() {
const element = document.getElementsByClassName("container")[0];
const doc = new jsPDF(
"p",
"px",
[element.clientWidth, element.clientHeight],
true
);
setExporting(true);
await createPdf({ doc, element });
doc.save(`charts.pdf`);
}
return (
<pdfContext.Provider value={{ exporting, setExporting }}>
<div className="App">
<button onClick={handleDownloadPdf}>Test</button>
<div className="container">
<Hidden />
<Foo />
</div>
</div>
</pdfContext.Provider>
);
}
export default App;
The component that I want to be hidden is <Hidden />, this is a simple component but let me show the code anyways:
const Hidden = () => {
const { exporting, setExporting } = useContext(pdfContext);
return (
<div
className="elementOne"
style={{ visibility: exporting ? "visible" : "hidden" }}
>
</div>
);
};
export default Hidden;
As you can see I want to use the context called pdfContext that sets the visibility of a component to hidden when the component is not being exported, and to visible when it's being exported, but this way is not really a good solution, as the component gets visible for a split second before exporting and in my opinion it's not a good design.
So if anyone has any solution or a workaround on how to export a component to a PDF using these libraries, but without showing it on a UI, that would be great.
I know that the way these components are being exported to a PDF is by converting the container to an image, and probably the way I am asking to do this is maybe impossible but then again it does not hurt to ask.

How to download the iframe as pdf document in react?I have tried using jspdf and kendo-react-pdf but getting blank document

import { PDFExport, savePDF } from '#progress/kendo-react-pdf';
const [contentRef, setContentRef] = useState('');
const downloadCertificate = () => {
const element: any =
document.querySelector('#certificate') || document.body;
savePDF(element, { paperSize: 'A4' });
};
const onClickDownload = () => {
downloadCertificate();
};
return (
<div>
<PDFExport ref={pdfExportComponent} paperSize="A4">
<iframe
id="certificate"
title="View your certificate"
className="u-els-margin-left-3x u-els-margin-right-3x"
width="776px"
height="600px"
srcDoc={contentRef}
/>
</PDFExport>
</div>
);
Using the above set of code to generate the pdf, I am importing the PDF Export and wrapping it around the block of code i want to export as pdf. Here the srcDoc of iframe is what I exactly want to export which assigned to a useState. So after the page renders the info is stored in srcDoc and I want to export this as pdf on click of the button which is part of the return.
currently iframes are not supported as part of the PDF export: https://www.telerik.com/kendo-react-ui/components/drawing/limitations-browser-support/#toc-elements-and-styles

Match background with users current weather conditions

I am new to React, trying to learn and I have this unsolvable problem. I have developed a weather app, I'm still working on it, but at this moment I am stuck for 3 days trying to have a background image that changes depending on the users weather conditions. I have tried something using the icon, from openweather API. I used the same method to get the icon (image from my folder) to match users weather conditions.
import React from "react";
export default function Background(props) {
const codeMapping = {
"01d": "clear-sky-day",
"01n": "clear-sky-night",
"02d": "cloudy-day",
"02n": "cloudy-night",
"03d": "cloudy-day",
"03n": "cloudy-night",
"04d": "cloudy-day",
"04n": "cloudy-night",
"09d": "shower-rain-day",
"09n": "shower-rain-night",
"10d": "rain-day",
"10n": "rain-night",
"11d": "thunderstorm-day",
"11n": "thunderstorm-night",
"13d": "snow-day",
"13n": "snow-night",
"50d": "fog-day",
"50n": "fog-night",
};
let name = codeMapping[props.code];
return (
<img
className="background"
src={`background/${name}.jpg`}
alt={props.alt}
size="cover"
/>
);
}
So... in order to get "icon" of the input city by the user I have to call "<Background cod={weatherData.icon} alt={weatherData.description} />" from the function "Search" which is the function handling the submit form and running api call for input city. But the image is not showing(img1), but to have the img as a background I would call <Background> from my App function(img2), but in this case I will not have access to the real icon value from the input city. I should mention I have a folder in "src" called background and the images names match the codes name from the mapping.
Thank you in advance!
current preview of my app
how I see in other documentation I should set a background
You can pass the code from Search.js as the state.
App.js
const codeMapping = {
"01d": "clear-sky-day",
"01n": "clear-sky-night",
};
export const App = () => {
const [code, setCode] = useState(null) // <-- We'll update this from Search.js
const [backgroundImage, setBackgroundImage] = useState("")
useEffect(() => {
// Set background value based on the code
setBackgroundImage(codeMapping[`${code}`])
}, [code]); // <-- useEffect will run everytime the code changes
return (
<div style={{
height: '100px',
width: '100px',
backgroundImage: `${backgroundImage || "defaultBackgroundImage"}`
}}>
<Search setCode={setCode} />
</div>
)
}
Search.js
import { WeatherContext } from './App';
export const Search = ({ setCode }) => {
const handleClick = (apiResponse) => {
// Some API call returning the actual code value here //
setCode(apiResponse)
}
return (
<input
onClick={() => handleClick("01n")}
type="button"
value="Change city"
/>
)
}

How do I use an image that was uploaded with mullter on mongodb in my react component?

So I uploaded an image on mongodb and now I want to use it in my react component but the file's path never seems to work:
router.post('/upload-avatar', upload.single('avatar'), uploadAvatar);
export default () => {
const [imageSource, setImageSource] = React.useState('');
const [imageAlt, setImageAlt] = React.useState('');
React.useEffect(() => {
axios.get(`http://localhost:8080/api/get-avatar`)
.then(res => {
setImageSource(res.data.posts[0].avatar.filePath.split('\\').join('\/'));
setImageAlt(res.data.posts[0].avatar.fileName);
})
}, []);
console.log(imageSource);
return (
<div className="avatar">
<img src={imageSource} alt={imageAlt} />
</div>
);
};
In my component I only get that image placeholder, like when the image is missing.
Your uploadAvatar must be:
For example:
(req, res, next) => {
const url = req.protocol + '://' + req.get('host')
const user = new User({
...
profileImg: url + '/public/' + req.file.filename
...
});
and response in react:
...
"user": {
...
profileImg: "http://localhost:8000/public/avatar.png"
...
}
...
response should be url also express server should be is running (For example):
"profileImg": "http://localhost:8000/public/avatar.png"
If you save path of file uploaded in db without url in reactjs app:
change:
<img src={imageSource} alt={imageAlt} />
to
<img src=`http://localhost:8000/public/${imageSource}` alt={imageAlt} />
You can use this article to get inspired:
React Single File Upload Tutorial with Node, Express and Multer
I have figured it out eventually. I cant just do:
<img src={imageSource} alt={imageAlt} />
cause it will never work for who knows what reason. But if instead I import the image from the folder to which multer saves the images, like so:
import someImage from './whatever/folder/multer/save/image/some-image.jpg'
it will work. I would have loved it to work the other way where I can pass the path from the http response directly to the image source attribute.

How to change font family dynamically in a functional component?

I have a component that fetches a random font from Google Font and pass it down to a functional component to render it.
function Palette() {
const url = `https://www.googleapis.com/webfonts/v1/webfonts?key=${key}`;
const [font, setFont] = useState("");
useEffect(() => {
const fetchFont = async url => {
const res = await axios(url);
const items = res.data.items;
const idx = Math.floor(Math.random() * items.length - 1);
setFont(items[idx].family);
};
fetchFont(url);
}, [url]);
return (
<div className="App">
<h1>Palette</h1>
<Card fontFamily={font} bgColor="green" color="white">
{font}
</Card>
</div>
);
}
How can I import this font dynamically inside the child component for styling?
How about this?
<Card style={{fontFamily: font, backgroundColor: 'green', color: 'white'}}>
{font}
</Card>
You can just set inline-css style in react like above. :)
You can append the the link tag that loads the font like this
const font = null;
const id = 'dynamic-font';
if (document.getElementById(id)) {
font = document.getElementById(id);
} else {
font = document.createElement('link');
font.rel='stylesheet'
font.id = id
document.head.appendChild(font)
}
font.href = // url to the font;
Then you can use the font in your CSS.
Another solution would be to actually download the .ttf / .otf files, then write the appropriate #font-face css class, create a CSS class that has the font-family set to the created font-face and apply the class to the desired element.

Resources