react-img-mapper blanck screen - reactjs

I have a project where i need to map specific areas of an image, for that i'm trying to use react-img-mapper, but when i try to run the example code, the only think that shows is a blanck screen, react do not log any erros. What am i doing wrong ?
import React from 'react';
import ImageMapper from 'react-img-mapper';
const Mapper = props => {
const URL = 'https://raw.githubusercontent.com/img-mapper/react-docs/master/src/assets/example.jpg';
const MAP = {
name: 'my-map',
// GET JSON FROM BELOW URL AS AN EXAMPLE
areas: 'https://raw.githubusercontent.com/img-mapper/react-docs/master/src/assets/example.json',
};
return <ImageMapper src={URL} map={MAP} />
}
export default Mapper;

Related

How to handle missing image in react 17?

I'm getting users data from an api which the profile pictures path could be invalid, so i was able to cover the part of using a default image, but the 404 error of the missing picture is still exists ... i wonder how can i prevent it. I went over ALL the solutions and still couldn't find a good one.
Here is my component that renders the image
import React, { useState } from 'react';
const Image = props => {
const { image } = props;
const [imageLoading, setImageLoading] = useState(true);
const imageLoading_Error = () => {
setImageLoading(false)
}
return (
<div item>
<img src={imageLoading
?
`https://myusers.com/user/${image}` // don't mind the address
:
`${window.location.origin}/assets/default.png`}
onError={() => imageLoading_Error()}
/>
</div>
)
}
export default Image;

React native base64 to pdf expo print

I want to print a pdf file on react native mobile app, I receive a base64 code from api and by using it I want to show customer his/her invoice pdf. I tried using Expo Print but I couldnt handle it, I keep getting
Error: Objects are not valid as a React child (found: object with keys {_40, _65, _55, _72}). If you meant to render a collection of children, use an array instead.]
I would appreciate any help!
import React, { Component } from 'react';
import { View, Text, Button, StyleSheet,TouchableHighlight } from 'react-native';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
import * as Print from 'expo-print';
const InvoiceScreen = async({ route, navigation }) => {
const { invoice} = route.params;
const my_uri = "data:application/pdf;base64"+invoice
console.log("DID INVIOCE COMEEE",invoice)
await Print.printAsync(
{uri:my_uri,
width: 595, height: 842 })
return (
<View></View>
);
};
export default InvoiceScreen;
replace your code with this:
const InvoiceScreen = async({ route, navigation }) => {
const { invoice } = route.params;
const my_uri = `data:application/pdf;base64,${invoice}`;
await Print.printAsync({uri:my_uri});
};
export default InvoiceScreen;
Maybe the problem is the data type of the "invoice" parameter, this must be a string which must be the base64 of the pdf file. Reference
If you are using Expo - Managed workflow (Expo CLI / Tool), to view pdf I recommend that you use https://www.npmjs.com/package/rn-pdf-reader-js
I also leave a simple implementation in view:
import React from "react";
import { View, StyleSheet, Dimensions } from "react-native";
import { globalStyles } from "../../constants/globalStyles";
import PDFReader from "rn-pdf-reader-js";
export default function XScreen({ navigation, route }) {
return (
<View style={globalStyles.backGround}>
<PDFReader
source={{
base64: route.params.source,
}}
style={styles.pdf}
/>
</View>
);
}
const styles = StyleSheet.create({
pdf: {
flex: 1,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
});
Note:
route.params.source =
data:application/pdf;base64,${response.data.data};
response.data.data = string base64 pdf

Implement Draft JS into Next JS, Text Editor Won't Show

I am trying to implement draft js as text editor into my next.js project. I have implemented all code based on official guide but the text editor won't show. Here is my code
index.js
import React, { Component } from 'react'
import { useRouter, Router } from 'next/router';
import Layout from '../../components/MyLayout';
import Settings from '../../components/Settings';
import MyEditor from '../../components/TextEditor';
import fetch from 'isomorphic-unfetch';
import {Editor, EditorState} from 'draft-js';
const Post = (props) => {
const router = useRouter();
const object = props.post.data[0];
return (
<Layout>
<h1>{object.title}</h1>
<div className="p-2 border bg-light text-right text-dark">Oleh: {object.username}</div>
<MyEditor/>
</Layout>
);
}
Post.getInitialProps = async function(context) {
const {id} = context.query;
const FormData = new URLSearchParams();
FormData.append('slug',`${id}`);
const res = await fetch(Settings.api+'viewPost',{
'method': 'POST',
'body': FormData
});
const post = await res.json();
console.log('aw');
return {
post
};
};
export default Post;
TextEditor.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';
export default function MyEditor() {
const [editorState, setEditorState] = React.useState(
EditorState.createEmpty()
);
return (
<Editor
editorState={editorState}
onChange={setEditorState}
/>
);
}
I really appreciate any answer. Thank you
It looks like you're doing the right thing - Draft-js is very much a low-level editing tool that you can build rich text-editing on top of - I'm guessing that the editor is actually rendering on the page, but you haven't added any toolbars or complex initial state so you're just seeing a blank page.
I reproduced a super basic Next JS example here: https://codesandbox.io/s/naughty-swirles-7nmbf?file=/pages/index.js and you'll see that the editor itself is 'invisible' as there is no styling applied and no toolbar. If you look further into the Draft-js docs you'll see you can apply initial config objects that will give it a basic style (which you can further customize as you wish).

Is this only possible with external URLs and not local?

I'm trying to make a photo gallery using react-images, the URLs are correct but the photos themselves are not loading into my web app. I get the broken image icon when switching themodalIsOpen:false to true.
Ive tried looking up examples of the same problems and alternatives, like if the component was configured right or if I am extending it right in the class.
import React, { Component } from 'react';
import Carousel, { Modal, ModalGateway } from 'react-images';
import blksmith from '../images/gallery/illustration/Blacksmith.jpg';
import mage from '../images/gallery/illustration/Mage.jpg';
const images =
[
{
src:{blksmith}
} ,
{
src:{mage}
}
];
class illuGallery extends Component {
state = { modalIsOpen: false }
toggleModal = () => {
this.setState(state => ({ modalIsOpen: !state.modalIsOpen }));
}
render() {
const { modalIsOpen } = this.state;
return (
<ModalGateway>
{modalIsOpen ? (
<Modal onClose={this.toggleModal}>
<Carousel
views={images}
/>
</Modal>
) : null}
</ModalGateway>
);
}
}
export default illuGallery;
This is in the actual gallery.js file, the web page that renders the gallery.
import React from 'react';
import Layout from "../components/layout";
import IlluPhotos from "../components/illustrationGallery";
import SEO from "../components/seo";
import './gallery.scss';
const GalleryPage = () => {
return (
<Layout>
<div style={{width:'100%',height:'250px'}}>
<SEO title="Gallery" />
<IlluPhotos/>
</div>
</Layout>
)
}
export default GalleryPage;
I am seeking some feedback on how to get this to work and what I did wrong, or what I should explore more.
So I ended up adding the pictures I wanted for the gallery to the public folder as mentioned farther down in this post
Since the https://localhost:8000 was appearing in front of the links to the images I wanted to use.
Thank you all for helping me find the answer!!
You don't need to import images.
According to react-images documentation, you just need to pass path to image as a string to <Carousel> component, like in this example below:
import React from 'react';
import Carousel from 'react-images';
const images = [{ src: 'path/to/image-1.jpg' }, { src: 'path/to/image-2.jpg' }];
class Component extends React.Component {
render() {
return <Carousel views={images} />;
}
}

Import image dynamically in React component

I have an Articles component that shows a blog page with listed articles.
render() {
const articles = {
...this.state.articles
}
const article = Object.keys(articles).map(cur => {
return <Article
key={this.state.articles[cur].id}
imgName={this.state.articles[cur].thumb}
title={this.state.articles[cur].title}
meta={this.state.articles[cur].meta}
clicked={() => this.detailedHandler(this.state.articles[cur].id)}
detailed={this.state.articles[cur].detailed} />
});
As you can see I pass image name with props to Article component.
I want then to display the appropriate image for each article.
How do I import an image in Article component based on the props I receive (props.imgName) from Articles component?
I used context.
const images = require.context('../../../assets/img', true);
loadImage = imageName => (assets(`./${imageName}`).default);
<img src={loadImage("someimage.png")} alt="" />
I don't know if this is an optimal solution, but it works.
You can load images dynamically from the API response with dynamic imports that is Stage 3 proposal as of now.
The resulting code should look something like:
loadImage = imageName => {
import(`./assets/${imageName}.jpg`).then(image => {
this.setState({
image
});
});
};
render() {
const { image } = this.state;
return (
<Fragment>
{image && <img src={image} alt="" />}
</Fragment>
);
}
View Codesandbox Demo
This feature is supported out of the box in create-react-app, If using other systems, you can use the Babel plugin
For anyone looking for a modern approach using async-await and custom react hooks, I found a pretty slick solution. Create a file called useImage.js and paste the following code:
import { useEffect, useState } from 'react'
const useImage = (fileName) => {
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [image, setImage] = useState(null)
useEffect(() => {
const fetchImage = async () => {
try {
const response = await import(`../assets/img/${fileName}`) // change relative path to suit your needs
setImage(response.default)
} catch (err) {
setError(err)
} finally {
setLoading(false)
}
}
fetchImage()
}, [fileName])
return {
loading,
error,
image,
}
}
export default useImage
Then just import the custom hook into your image component, mine looks something like this:
import useImage from '../../hooks/useImage'
import Typography from './Typography' // simple plain-text react component
const Image = ({ fileName, alt, className, ...rest }) => {
const { loading, error, image } = useImage(fileName)
if (error) return <Typography>{alt}</Typography>
return (
<>
{loading ? (
<Typography>loading</Typography>
) : (
<img
className={`Image${
className
? className.padStart(className.length + 1)
: ''
}`}
src={image}
alt={alt}
{...rest}
/>
)}
</>
)
}
export default Image
The nice thing about this solution is that no matter where your component is in relation to your assets folder, the react hook is always in the same place, so the relative path stays the same.
there are my way, works nicely:)
import React, {useState} from "react"
const getFavorites = (props) => {
const {item, favouritesNote} = props;
const [image, setImage] = useState("");
(function (imageName) {
import(
`../../../../assets/images/chart/favorite${imageName ? "_active" : ""}.png`
).then((image) => setImage(image.default));
})(favouritesNote[item.id]);
return (
<div>{image && <img alt="" className="img-responsive" src={image} />}</div
)
}
Note: All these comments work complementary with the #jadenRose hook solution which is a great abstraction.
You can import the images dynamically with the native js dynamic import('') , there's no need for React Lazy.
However, you have to be aware of the path/content you pass to the import(path) because depending on how you are planning to include the images to import in the final bundle there could be restrictions. There are two main ways:
Note: This is for Rollup, in Webpack i didn't try it but should be similar
a)- Making rollup automatically include the possibles files to import while creating the bundle using the official plugin https://www.npmjs.com/package/#rollup/plugin-dynamic-import-vars please read the doc and notice how there are important restrictions in the 'path' string, essentially you should just set the file name in the variable, the rest of the path have to be fixed in the import('') in order to provide rollup a restricted scope to import. eg:
OK
import(../assets/img/${fileName}.svg)
Wrong
import(filePath)
b)- Include in the bundle programmatically the files you can dynamically import example
//rollup.config.js
import copy from 'rollup-plugin-copy';
plugins: [
copy({
targets: [ { src: 'src/assets/icons/*', dest: 'lib/assets/icons' },],
}),
…
],
With this option b) you have no restrictions on the variable content but have to be careful with what you included in the bundle.
Conclusion: You can use dynamic import(...) but if you not properly handle the files inclusion on the bundle, it can be possible they are excluded and then the dynamic import will fail in the consumer.
I found this worked best for me:
I created an index file inside the images folder. there I imported all the images I have and created a class component with the variables assigned to each image import. this is because when we import an image in react using the import statement, that is, import someImage from './somewhere' react assigns the 'someImage' variable to a module with a 'static media' address, my terminology there might be wrong. Here is the example:
import image13_1 from './image13_1.png';
import image13_2 from './image13_2.png';
import image13_3 from './image13_3.png';
import image13_4 from './image13_4.png';
import image13_5 from './image13_5.png';
import image13_6 from './image13_6.png';
import image13_7 from './image13_7.png';
export class IMG{
1= image13_1
2 = image13_2
3 = image13_3
4 = image13_4
5 = image13_5
6 = image13_6
7 = image13_7
}
export default IMG;
from here I just import the IMG class and create an instance of it and call the image number a property:
var img = new IMG()
console.log('img',img[1]

Resources