error in displaying pdf in react-pdf - reactjs

I am new new to react, I am trying to display a pdf file on browser. I am getting an error as failed to load PDF. I am trying to run the sample program given in https://www.npmjs.com/package/react-pdf.
App.js
import React, { Component } from 'react';
import { Document, Page } from 'react-pdf';
class MyApp extends Component {
state = {
numPages: null,
pageNumber: 1,
}
onDocumentLoad = ({ numPages }) => {
this.setState({ numPages });
}
render() {
const { pageNumber, numPages } = this.state;
return (
<div>
<Document
file="./1.pdf"
onLoadSuccess={this.onDocumentLoad}
>
<Page pageNumber={pageNumber} />
</Document>
</div>
);
}
}
export default MyApp;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Error screenshot

Question is old but hope this help someone. I faced this issue and found a solution here https://github.com/wojtekmaj/react-pdf/issues/321.
import { Document, Page, pdfjs } from 'react-pdf';
Add this to your constructor.
constructor(props){
super(props);
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
}

You load the file using file="./1.pdf" I believe that might be the problem.
If you have a file structure like:
src
App.js
components
ShowPdfComponent.js
1.pdf
public
bundle.js
Then you need to move the 1.pdf to public folder like this:
src
App.js
components
ShowPdfComponent.js
public
bundle.js
1.pdf
Because when your compiled javascript code is being executed from public/bundle.js and bundle.js does not know how to get to src/components/1.pdf in file system.
There might be also a difference between production/development environment if you are using webpack and webpack-dev-server.
Look at react-pdf example. It has flat file structure. That is the reason why it works.

if you are using create-react-app then you need to import differently like
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack'
because it uses webpack under the hood.

You can import the pdf file using import samplePdf from './1.pdf' and can use directly like file={samplePdf} in your Document tag.

Here is the minimum setup you need to be able to display your pdf in react TypeScript:
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist#${pdfjs.version}/legacy/build/pdf.worker.min.js`;
const YourComponentReact = ({url}: {url: string}) => {
return (<Document file={url}>
<Page pageNumber={1} />
</Document>)
}
You can add a quick button if you want to be able to change pages
You only need to download react-pdf and #types/react-pdf if you use typescript.

adding pdfjs to import and using it like this hellped
import { Document, Page, pdfjs } from 'react-pdf'
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist#${pdfjs.version}/legacy/build/pdf.worker.min.js`;
in the same file i need to show my pdf

Related

import components from create-react-library subfolder

I have been trying to use create-react-library and so far it works, but I can only import components successfully from index.js. If I try to make another file , I recieve an import error.
The file structure is as such
example
\ Node Module
\ public
\ src
| App.js
| index.js
...
src
\ Patterns
| index.js
| button.js
Currently I can only successfully import components from index.js of the main src. Is there a way to successfully import components from folders such as Patterns or another file?
\ App.js ( example )
Importing button gives me an error "Cant import button from neo"
import React from 'react'
import { ExampleComponent,Button} from 'neo'
import {Test} from 'neo/Patterns';
import 'neo/dist/index.css'
const App = () => {
return (
<>
<Test />
<Button text='Click me' />
<ExampleComponent text="Create React Library Example 😄" />
</>
)
}
export default App
Please check if this is what you're trying to achieve.
index.js will be exporting required components like this,
import ExampleComponent from './ExampleComponent/ExampleComponent';
// ExampleComponent is placed inside a folder named ExampleComponent
import Patterns from './Patterns/Patterns';
// Patterns is placed inside a folder named Patterns
export { ExampleComponent, Patterns };
Patterns.js can look like this,
import React from 'react'
const Patterns = () => {
return <div>Patterns Component sample</div>
}
export default Patterns;
ExampleComponent.js can look like this,
import React from 'react'
import styles from './styles.module.css'
const ExampleComponent = ({ text }) => {
return <div className={styles.test}>Example Component: {text}</div>
}
export default ExampleComponent;
In the consumer level (in this case, example folder), in any jsx, like App.js you can refer those exported components like,
import { ExampleComponent, Patterns } from 'neo'
return (
<Patterns />
)

Use NPM package in React Component

I try to use Pannellum NPM package in my React component.
Pannellum's API can be used like this:
pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
I thought the following code:
import React, { Component } from 'react';
import './App.css';
import pannellum from 'pannellum';
class App extends Component {
componentDidMount() {
pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
}
render() {
return (
<div id="panorama"></div>
);
}
}
export default App;
would work. However it does not. I get TypeError: __WEBPACK_IMPORTED_MODULE_2_pannellum___default.a.viewer is not a function.
Tried also a different import statements:
import { pannellum } from 'pannellum';, const pannellum = require('pannellum'); but these also don't work.
What's interesting, Pannellum's API javascript code is bundled and once I comment out componentDidMount() and try to use the API via Chrome Dev Tools console once the page is loaded, it works. However there are no CSS styles applied.
I clearly do something wrong.
I have seen 360-react-pannellum package source code but I need access to the whole API, not just rendering so it does not suit my needs.
Thank you for your help.
Looking at the source code of pannellum, it does not export any module but puts everything on the window object.
Try importing the code and using it directly from the window.
import React, { Component } from 'react';
import './App.css';
import 'pannellum';
class App extends Component {
componentDidMount() {
window.pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
}
render() {
return (
<div id="panorama"></div>
);
}
}
export default App;
Try
componentDidMount() {
window.pannellum.viewer('panorama', {
"type": "equirectangular",
"panorama": "https://pannellum.org/images/alma.jpg"
});
}

Can we integrate react component into Aurelia project?

I have created one react component and build it using webpack and deployed on server. I want to integrate this component into Aurelia Project.
I tried using below npm module:
https://www.npmjs.com/package/aurelia-react-loader
In above module mentioned, component name need pass into html file. like in example my-react-component.js is passing into html file.
But my React Component is loading into root in html tag using below code:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render((
<App/>
), document.getElementById('root'));
and after running webpack module, it is creating one JavaScript file that is called index_bundle.js file. Here imported App module is main js component. It is rendering into index.html on root element via ReactDOM.
So I am not sure, How I am going to integrate React component link or url into Aurelia application?
Please let me know if you have any doubts in question. I can do explain in detail.
Thanks in advance.
Harish
Yeah, it's really easy to integrate a react component in to an Aurelia app. Check out my project where I do just that here: https://github.com/ashleygrant/aurelia-loves-react
I'm not even using the loader plugin you mentioned.
Here's how to wrap a third-party react component in an Aurelia custom element:
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDatePicker from 'react-datepicker';
import { noView, bindable, inject } from 'aurelia-framework';
#noView(['react-datepicker/react-datepicker.css'])
#inject(Element)
export class DatePicker {
#bindable selectedDate;
#bindable onChange;
constructor(element) {
this.element = element;
}
selectedDateChanged() {
this.render();
}
render() {
ReactDOM.render(
<ReactDatePicker
selected={this.selectedDate}
onChange={date => this.onChange({ date: date })}
/>,
this.element
);
}
// How to use native DOM events to pass the changed date
/*render() {
ReactDOM.render(
<ReactDatePicker
selected={this.selectedDate}
onChange={date => {
let event = new CustomEvent('change', { 'detail': date });
// Dispatch the event.
this.element.dispatchEvent(event);
}
}
/>,
this.element
);
}*/
}
And here's how to do it while using a custom react component that is part of the Aurelia project:
import React from 'react';
import ReactDOM from 'react-dom';
import { noView, bindable, inject } from 'aurelia-framework';
import FormattedDate from '../react-components/formatted-date';
#noView()
#inject(Element)
export class ReactDate {
#bindable date;
#bindable format = 'dddd, MMMM D, YYYY';
constructor(element) {
this.element = element;
}
dateChanged() {
this.render();
}
formatChanged() {
this.render();
}
render() {
ReactDOM.render(
<FormattedDate
date={this.date}
format={this.format}
/>,
this.element
);
}
}
As you can see, it's pretty simple. I like doing it by hand rather than using the loader as I can set up databinding for each property so it works in a more "Aurelia-ey" way.

SnapSVGAnimator.js generates errors when loading in React web app

SnapSVG extension for Adobe Animate.cc 2017 is able to create interactivity and animations for the web. I'm currently trying to use an exported SnapSVG Adobe Animate.cc project in my REACT JS WebApplication.
What I've done so far:
Imported snapsvg-cjs from npm( modified snapsvg to use succesfull in React)
Imported axios to load custom json file generated from SnapSVG extension in Animate.cc
Excluded minified code with eslintignore from SnapSVGAnimator. lib, generated while publishing SVG animation from Animate.cc to work properly without the ESlinting warnings.
Create a componentDidMount function
current code:
import React, {Component} from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { SVGAnim } from './SnapSVGAnimator.js';
import snapsvg from 'snapsvg-cjs';
componentDidMount(){
axios.get(jsonfile)
.then(response => {
const json = response.request.responseText;
const comp = new SVGAnim(json);
console.log(comp)
});
}
Problem
Following error appears while I log const comp.
Uncaught (in promise) TypeError:
_SnapSVGAnimator.SVGAnim is not a constructor
During the publish render in Animate.cc there are two libs generated; snapsvg.js and SVGAnimator.js
You can import snapsvg-cjs from NPM but SVGAnimator.js isn't available. Importing SVGAnimator.js with the ES6 approach from a curtain directory in your ReactApp isn't possible, not even by excluding it from linting with /* eslint-disable */ 1000 warnings still appears.
Instead of that, add the code to your index.html file, located in the public folder this way
(I've used create-react-app to build this project):
<script type="text/javascript" src="%PUBLIC_URL%/libs/SnapSVGAnimator.min.js"></script>
This is the working code:
import React, { Component } from 'react';
//axios for asnyc usage*/
import axios from 'axios';
//Snapsvg-cjs works out of the box with webpack
import Snapsvg from 'snapsvg-cjs';
//snap.json is located in the public folder, dev-build folder(ugly approach).
let jsonfile = "snap.json";
class SVGAnimator extends Component {
constructor(props){
super(props);
this.state = {
data: ''
}
}
componentDidMount(){
axios.get(jsonfile)
.then(response => {
this.setState({ data: response.data })
});
}
getSVG(){
if(this.state.data){
const container = document.getElementById('container');
const SVG = new window.SVGAnim(this.state.data, 269, 163, 24)
container.appendChild(SVG.s.node);
}
}
render() {
return (
<div id="container">
{ this.getSVG()}
</div>
);
}
}
export default SVGAnimator;

Using marked in react

I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview

Resources