react-pdf: Image not updating when Image src is updated

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…

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 (fields.designs.length > 0 && fields.designs[0].image != undefined) {
       var designThumb = fields.designs[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.headerLeftWrapper}>
                   <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.headerRightWrapper}>
                   <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>


             <Image style={{width:400, height:400, marginVertical: 15, marginHorizontal: 100}} src={designThumb} />


             <View style={styles.section}>
               <Text style={styles.body}></Text>
             </View>

             <View style={[styles.section, { bottom: 1 }]}>
               {Footer}
             </View>

           </Page>

         </Document>
     )
 
}
<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>

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…

  • I can see it in the console when I update the field on the form.
  • If I hard code it into the Image src, I can see the image appear on the PDF.

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?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 26 (5 by maintainers)

Most upvoted comments

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 😃

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"/>

@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

Access to XMLHttpRequest at ‘https://storage.googleapis.com/samclientpreprod/MicrosoftTeams-image (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

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>

### 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…

@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.