Closed serkyen closed 6 years ago
I have tried everything but still unable to get this to work.
I have tried storing and getting the values from...
All do the same thing which is, gets the value correctly only when the page first renders, but making any changes after the page has loaded, and clicking on the print button again does not update the image src value, only the other values. Seems that the Image src value is set in stone when the PDF first loads.
How come Text can update but Image can't? Please help...I am stuck on this issue for days now.
Thanks in advance.
Hey @serkyen Sorry to hear that. I'm back to work now. I promise I'll check this issue tomorrow
@diegomura Thank you :)
@serkyen fixed!
Silly issue, but also hard to see beforehand.
I also implemented cache for images. So now, if you're rendering an image that was in the document in the past, it won't trigger another network request. This will make re-rendering way more faster. You can disable it of course by passing cache={false}
to Image
.
Tomorrow I'll publish a new version and will be available for you to use
@diegomura Awesome! Am waiting for the new version :) Thanks for the cache feature as well! 👍
@diegomura It looks like this is still not working for me after updating to 1.0.0-alpha.19
Couple issues...
Also, I get the following errors on the console when I change the src of the Image.
@diegomura Here are the errors I get each time I change the Image src (making the selection on the form).
What do you mean by click the print again
?
I think I will have to know a bit more about how you're using the library in order to understand what's going on. I tried again and image upload seems to be working fine. This is an example of how you can test image upload:
class MyDocument extends React.Component {
state = { image: 'someurl' }
componentDidMount() {
setTimeout(() => {
setState({ image: 'otherurl' })
}, 1000)
}
render() {
return (
<PDFViewer>
<Document>
<Page>
<Image src={this.state.image} />
</Page>
</Document>
</PDFViewer>
)
}
}
Ok here is how I am using it....
import React from 'react';
import PropTypes from 'prop-types';
import { withTracker } from 'meteor/react-meteor-data';
import {browserHistory, withRouter} from 'react-router';
import { BlobProvider, PDFViewer, PDFDownloadLink, Page, Text, View, Image, Document, StyleSheet } from '@react-pdf/renderer/dist/react-pdf.browser.cjs.js';
import { styles } from '../pdf/Styles.js';
...
class OrderForm extends React.Component {
constructor(props) {
super(props);
// this.state = {
// };
};
generateOrderPDF = (fields) => {
var businessData = this.props.user.business;
if (fields.contact != undefined || fields.contact != '') {
var orderName = this.generateOrderName();
var contactName = this.generateContactName();
} else {
var orderName = "";
var contactName = "";
}
if (this.props.designsList.length > 0 && this.props.designsList[0].image != undefined) {
var designThumb = this.props.designsList[0].image;
} else {
var designThumb = '';
}
console.log(designThumb)
return (
<Document title="Order">
<Page wrap size="A4" style={styles.page}>
<View style={styles.header}>
<View style={{textAlign:'center'}}>
<Image
style={styles.logo}
src={businessData.logo === '' ? null : businessData.logo}
/>
<Text style={{padding: 5, fontSize:10}}>{businessData.name}</Text>
</View>
<View style={styles.leftWrapper}>
<Text>Order Name: {orderName === "" ? null : orderName}</Text>
<Text>Status: {fields.status === "" ? null : fields.status}</Text>
<Text>Ordered by: {contactName === "" ? null : contactName}</Text>
<Text>Ordered for: {fields.orderedFor === "" ? null : fields.orderedFor}</Text>
<Text>Note: {fields.note === "" ? null : fields.note}</Text>
</View>
<View style={styles.rightWrapper}>
<Text>Date: {moment(new Date()).format('DD/MM/YYYY')}</Text>
<Text>Occasion Date: {moment(fields.occasionDate).format('DD/MM/YYYY')}</Text>
<Text>Receiving Date: {moment(fields.receivingDate).format('DD/MM/YYYY')}</Text>
</View>
</View>
<View style={styles.section}>
<View style={[styles.leftWrapper, { width:'150', textAlign:'center' }]}>
<Image cache={false} style={{width:150, height:150}} src={designThumb} />
</View>
<View style={[styles.rightWrapper, { width:'300' }]}>
</View>
</View>
<View style={styles.section}>
<Text style={styles.body}></Text>
</View>
<View style={[styles.section, { bottom: 1 }]}>
{Footer}
</View>
</Page>
</Document>
)
}
render() {
const { getFieldDecorator, getFieldValue, getFieldsValue } = this.props.form;
return (
<div>
<Form onSubmit={this.handleSubmit}>
<FormItem style={{float: 'right', zIndex: '1000', margin: '0px'}}>
{!this.props.loading ?
<BlobProvider document={this.generateOrderPDF(this.props.form.getFieldsValue())}>
{({ url }) => (
<a href={url} target="_blank" style={{marginRight:'5px'}} className="download-pdf-btn ant-btn btn-secondary ant-btn-primary">Print</a>
)}
</BlobProvider>
: null}
<Button loading={Session.get('processing')} className="btn-secondary" disabled={this.props.uploading} type="primary" htmlType="submit">Save</Button>
</FormItem>
<FormItem
colon={false}
label="Status"
>
<div>
{getFieldDecorator('status', {
initialValue: this.props.doc.status,
onChange:this.setFormValues,
rules: [{
required: true,
message: 'Please select a status.'
}]
})(
<Select
showSearch
optionFilterProp='label'
filterOption={(input, option) => option.props.label.toLowerCase().indexOf(input.toLowerCase()) >= 0}
>
<Option key="0" value="Unconfirmed" label="Unconfirmed">Unconfirmed</Option>
<Option key="1" value="Confirmed" label="Confirmed">Confirmed</Option>
<Option key="2" value="Processing" label="Processing">Processing</Option>
<Option key="3" value="Completed" label="Completed">Completed</Option>
<Option key="4" value="Cancelled" label="Cancelled">Cancelled</Option>
<Option key="5" value="Refunded" label="Refunded">Refunded</Option>
</Select>
)}
</div>
</FormItem>
...
</Form>
</div>
)
}
}
export default withTracker( props => {
const user_sub = Meteor.subscribe('users.safeFields');
const loading = !user_sub.ready();
const user = Meteor.users.findOne(Meteor.userId());
const designsList = Session.get('designsList');
return {
loading,
designsList,
};
})(Form.create({})(withRouter(OrderForm)));
I have omitted a lot of code because of irrelevance. Form is from antD Form component.
Still... tried again using the same principles you're using and everything worked fine:
const MyDocument = ({ image }) => (
<Document>
<Page style={styles.page} wrap debug>
<Image src={image} />
</Page>
</Document>
)
class App extends React.Component {
state = { image: '/quijote1.jpg', counter: 10 }
componentDidMount() {
setInterval(() => {
if (this.state.counter > 0) {
this.setState({ image: this.state.image === '/quijote1.jpg' ? '/quijote2.png' : '/quijote1.jpg' })
}
}, 2500)
}
render() {
return (
<BlobProvider document={<MyDocument image={this.state.image} />}>
{({ url }) => {
return <a href={url}>Print</a>
}}
</BlobProvider>
)
}
}
Please observe that you can now define your PDF document as a separate component and pass <MyDocument someProps />
to the BlobProvider
. I don't know what might be happening, but that error means that the lib is trying to edit an already rendered PDF instance. Internally, it creates a new instance on each rerender
Ok I think the issue is revolving around a CORS problem. I am getting this error as well...
Access to fetch at 'https://link-to-image-at-amazon-S3.jpg' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Any ideas?
Not sure how a cors issue can cause the error message you sent. But I would suggest to resolve that problem first. If the lo cannot get the image still renders.
There’s no much I can do to solve that issue. It seems that you cannot access the image from your dev server. You will have to change access headers of your resources
@diegomura Good news is that I solved the errors with a setTimeout, and I also fixed the CORS problem and I am able to render the PDF with the updated image, but there seems to be one more error showing up.
Here is the code I have now...
class OrderForm extends React.Component {
constructor(props) {
super(props);
this.state = {
image: Session.get('designsList').length > 0 ? Session.get('designsList')[0].image : ''
};
};
...
//Runs each time a design is selected on the form.
onDesignSelect = (v, index) => {
Session.set('pdfPrintable', false);
...
Session.set('designsList', z);
this.setState({
image: Session.get('designsList')[0].image
});
setTimeout(function (){
Session.set('pdfPrintable', true);
}, 200);
}
generateOrderPDF = (fields) => {
return (
<Document title="Order">
<Page wrap size="A4" style={styles.page}>
<View style={styles.section}>
<Image cache={false} style={{width:150, height:150}} src={this.state.image} crossorigin="anonymous"/>
</View>
</Page>
</Document>
)
}
{this.props.pdfPrintable ?
<BlobProvider document={this.generateOrderPDF(this.props.form.getFieldsValue())}>
{({ url }) => (
<Button href={url} target="_blank" type="primary">Print</Button>
)}
</BlobProvider>
: null}
So if I remove the setTimeout function and just Session.set('pdfPrintable', true);
, the stream.push errors comes back. There's probably a better way to fix this but I guess it will be ok for now.
So here is the issue now...
When the page first loads, all is well. No errors and the PDF prints as desired. As soon as I make a change (select a design from the form which will update this.state.image), the PDF still updates and renders ok, but I get this error in the console...
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. in InternalBlobProvider (created by BlobProvider) in BlobProvider (created by OrderForm)
If I change the design again, the error does not show up again. Basically, the error only shows up the first time I change this.state.image but not anytime after. I guess I could ignore this error because everything is working anyway but looking at the structure of the code above, do you know how I can avoid this error or why it is showing up?
Thanks for your all your help by the way...really appreciate it.
anyone else with same CORS problem ? crossorigin="anonymous" and cache={false} doesn't work for me :(
Same CORS issue with me I used crossorigin="anonymous" and cache={false} doesn't work for me.
Access to XMLHttpRequest at 'https://dgzr31xopt5l5.cloudfront.net/profile_pics/FnB7YJOtWsVyvHN8dKEyvbNmV9V21570438881789.png' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Anyone has solved this issue. Thanks in advance :)
i am facing this CORS issue in google chrome only , in firefox it works perfectly but in chrome i get the CORS issue. Kindly help.
Hey all. Just for reference, this is how I am loading images on the PDF and everything works.
<Image cache={false} src={image+"?rnd="+Math.random()} crossorigin="anonymous"/>
### Am unable to retrieve the images on the browser.
<Image style={{ width: 400, height: 400, marginVertical: 15, marginHorizontal: 100,border:'1px solid red' }}
src="https://image.shutterstock.com/image-photo/bright-spring-view-cameo-island-260nw-1048185397.jpg"
/>
<Text style={styles.movieTitle}> 音声サービス5年特割パック</Text>
And if i register a font which is support to Japanese character
Font.register(${__dirname}fonts/Nasu-Regular.ttf
, {
family: "Nasu-Regular"
});
Error: Unknown font format
at Object.push../node_modules/@react-pdf/fontkit/dist/fontkit.browser.es.js.fontkit$1.create (fontkit.browser.es.js:68)
at FontSource._callee2$ (font.js:35)
at tryCatch (runtime.js:45)
at Generator.invoke [as _invoke] (runtime.js:271)
at Generator.prototype. [as next] (runtime.js:97)
at asyncGeneratorStep (asyncToGenerator.js:3)
at _next (asyncToGenerator.js:25)
### Please help...
Hey all. Just for reference, this is how I am loading images on the PDF and everything works.
<Image cache={false} src={image+"?rnd="+Math.random()} crossorigin="anonymous"/>
Hey @serkyen,
thanks for your reference but I don't think there's a property crossorigin
on <Image>
Any update on this issue?
Hey all. Just for reference, this is how I am loading images on the PDF and everything works.
<Image cache={false} src={image+"?rnd="+Math.random()} crossorigin="anonymous"/>
Unfortunately cache={false}
is not working. The random suffix makes the URL unique so the image is freshly downloaded and not using the cache, and this works. check also the observation at https://github.com/diegomura/react-pdf/issues/1283#issuecomment-833892090
Access to XMLHttpRequest at 'https://storage.googleapis.com/samclientpreprod/MicrosoftTeams-image%20(1)-1637660753530-740499763.png' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I am facing this issue when I am fetching image dynamically
I have same issue, and almost everyone is talking about Amazon S3 bucket, And I am using url of my domain to show an image, Where I am getting IMAGE URL from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
https://github.com/diegomura/react-pdf/issues/929
Please suggest anything that works with normal domain url image
Is there an update on this issue for using a simple url?
Tried using [https://sv.wikipedia.org/wiki/Playstation_5#/media/Fil:PlayStation_5_and_DualSense_with_transparent_background.png] and other public images, but cannot load them into the PDF?
Is there an update on this issue for using a simple url?
Tried using [https://sv.wikipedia.org/wiki/Playstation_5#/media/Fil:PlayStation_5_and_DualSense_with_transparent_background.png] and other public images, but cannot load them into the PDF?
Were you able to fix this?
@diegomura Good news is that I solved the errors with a setTimeout, and I also fixed the CORS problem and I am able to render the PDF with the updated image, but there seems to be one more error showing up.
Here is the code I have now...
class OrderForm extends React.Component { constructor(props) { super(props); this.state = { image: Session.get('designsList').length > 0 ? Session.get('designsList')[0].image : '' }; }; ...
//Runs each time a design is selected on the form. onDesignSelect = (v, index) => { Session.set('pdfPrintable', false); ... Session.set('designsList', z); this.setState({ image: Session.get('designsList')[0].image }); setTimeout(function (){ Session.set('pdfPrintable', true); }, 200); }
generateOrderPDF = (fields) => { return ( <Document title="Order"> <Page wrap size="A4" style={styles.page}> <View style={styles.section}> <Image cache={false} style={{width:150, height:150}} src={this.state.image} crossorigin="anonymous"/> </View> </Page> </Document> ) }
{this.props.pdfPrintable ? <BlobProvider document={this.generateOrderPDF(this.props.form.getFieldsValue())}> {({ url }) => ( <Button href={url} target="_blank" type="primary">Print</Button> )} </BlobProvider> : null}
So if I remove the setTimeout function and just
Session.set('pdfPrintable', true);
, the stream.push errors comes back. There's probably a better way to fix this but I guess it will be ok for now.So here is the issue now...
When the page first loads, all is well. No errors and the PDF prints as desired. As soon as I make a change (select a design from the form which will update this.state.image), the PDF still updates and renders ok, but I get this error in the console...
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. in InternalBlobProvider (created by BlobProvider) in BlobProvider (created by OrderForm)
If I change the design again, the error does not show up again. Basically, the error only shows up the first time I change this.state.image but not anytime after. I guess I could ignore this error because everything is working anyway but looking at the structure of the code above, do you know how I can avoid this error or why it is showing up?
Thanks for your all your help by the way...really appreciate it.
Hello @serkyen How did you fix the CORS issue?
OS: mac os 10.13.4
React-pdf version: 1.0.0-alpha.17
Description: I am trying to update the PDF with an image dynamically after making changes to a form. Here is the code...
All other fields on the PDF update accordingly when the value is changed on the form, but the image does not. I am certain that the designThumb is a valid link to an image because...
What's unusual is that when I go to the playground, and remove the link from one of the Image's src, it updates as it should with no issues.
Am I doing something wrong?