I am using CraftMyPDF API to generate a custom document and PDF Viewer to display the results. In DEV environment, I must use “Enhanced Script Exec Time” to allow CraftMyPDF time to work and it is working. In PROD environment, the CraftMyPDF takes too long. The document is produced but the async nature of the page is trying to display the document before it is returned from the API. Is there a WAIT function or a Test for existence of a file?
Hello @Richard_Munger
Could you show the logic of how you use the PDF API. Or you can make a simple ui-builder example page and provide us with your appId and path to the example page so we can play with it.
Regards
The app id is DEC6B808-645B-7B62-FF97-8D7C3B617700.
The page(s) affected are “landing00” and “landing01”.
Landing00 collects the client data & passes it to Landing01.
Landing01 “On Page Enter” event calls the external API, files the returned document with a name associated with the client, then positions the document for presentation.
The PDF Viewer “pdfUrl” event displays the proper document.
PS…You will notice that after I got the CraftMyPDF API service working in DEV, I disabled calls to the API from DEV to help save on the metered usage count from the vendor.
Let’s summarize:
- OnPageEnter you run an API Service to generate pdf
- once the service returns a result you put it into the PageData as “pdfURL” for instance
- then you have a UI to display the pdf by the “pdfURL” property in the PageData but there is no value since the second step is not completed yet
Is that correct?
If so, it happens because of lifecycle handlers like “OnBeforePageEnter/OnPageEnter/OnBeforeMount/OnMounted” do not block the rendering processing and all others still be rendered even if such handlers have long logic
To solve the issue you need to have a logic to show/hide UI components until your data is ready and it’s possible to use in that component
Regards,
Vlad
Exactly!
So my original question for this issue is “async nature of the page is trying to display the document before it is returned from the API. Is there a WAIT function or a Test for existence of a file?”. Is there such a function (Wait or Test for existence) within Backendless or do I have to create one?
you do not need any wait block, just rely on the value (returned from the API Service) in the page data
- if there is the value show the component
- if not do not show the component
to show/hide you can use VisiblityLogic handler
Vlad,
This does not solve the problem of the page component waiting for the PDF document to become available.
I do not want to page to be displayed without the PDF document. The use of the Visibility controls only mask the “document not available” message displayed by the PDF Viewer component.
ok, it seems like I missed something in your requirements, let’s rollback and go through your points:
- OnPageEnter you run an API Service to generate pdf
- Once the service returns a result you want to display the pdf
- Until the pdf is generated you do not want to display the page (what should be displayed in that case?)
- you do not want to hide the component on the page until the pdf is generated, (do you want to show another page)?
the misunderstanding I assume with these last two points
could you please correct this?
- Correct
- Correct
- Ideally, the page could be displayed immediately IF the PDF Viewer component could monitor for the existence of the PDF document and then display the PDF when the API has delivered it.
* I cannot have the user refresh the page because the session would lose its values from the first page.
* If there were a “refresh” function for the PDF Viewer component without forcing a refresh of the entire page, this could be helpful to programmatically force a refresh after a programmed wait period. - Correct, do not hide the PDF Viewer component as it will confuse the viewer/user
I have played with the WAIT function of TIMERS but it does not seem to be working well for me in PROD mode. Maybe I have not set the proper time value yet.
- Ideally, the page could be displayed immediately IF the PDF Viewer component could monitor for the existence of the PDF document and then display the PDF when the API has delivered it.
Let’s add more details: generating the file takes 10 seconds what do you expect to see on the page?
- empty page
- the PDF Viewer component with empty content
- spinner
- etc.
- I cannot have the user refresh the page because the session would lose its values from the first page.
You do not need to refresh the entire page
- If there were a “refresh” function for the PDF Viewer component without forcing a refresh of the entire page, this could be helpful to programmatically force a refresh after a programmed wait period.
once you set the valid PDF URL it will display it, why do you need to refresh it if it’s not generated yet (since the generating request is not completed yet and you do not have URL to the file)
I have played with the WAIT function of TIMERS but it does not seem to be working well for me in PROD mode. Maybe I have not set the proper time value yet.
WAIT and Timers is a bad solution since you do not know how much time the pdf generation takes
Are you familiar with the DataModels and Renders concept in the UI-Builder?
https://backendless.com/docs/uibuilder/ui_rendering.html
You already have the mechanism you are looking for:
- run async API
- once it’s done set the value to a DataModel
- since the DataModel has changed it runs rerender
- rerenders runs all LogicHandlers for all components beneath the DataModel
- a LogicHandler may return new value according to values in the DataModel
Hi Vlad,
I read up on the data models. I think the timing issue may still be a problem. Here are the sequence of events as currently implemented:
Here is the remainder of the message that did not get through:
Are you suggesting that to cause a re-render of the component, that I use one of these:
- have the PDF Viewer component use Page Variables or other local data model storage?
- that I move the renamed file to App Data and have the PDF Viewer access the App Data?
Will either of these do what you are suggesting?
Yes, the component must have data-binding or LogicHandler to get the PDF file URL, once in a data model the value changes the component get a new URL and then download and display it
- that I move the renamed file to App Data and have the PDF Viewer access the App Data?
I am not sure I get this, could you please add more details?
Or just describe your vision of what it should look like at the end
- open the page
- run the API service
- while it loads show this… in the UI
- once it’s loaded display the following …
- if the API request fails we need to show this content…
- and so on…
I’m currently capturing CraftMyPDF API returned info into Page Data. Since that data name is static, I have to rename it (in Page Data) and then pass it to the PDF Viewer. How are you suggesting changes that would result in a re-render of PDF Viewer?
I am not sure I understand why you need to rename it in the PageData
Vlad,
The PDF document being customized is a contract. It seems that the API can only return a static document name to a static location. I need to ensure that the document is named correctly to be attributed to the proper client. Additionally, the document needs to be renamed before a new API request overlays the prior API result.
You can specify the name of the final PDF file before the file is generated.
Mark,
In a prior problem ticket, you had told me CraftMyPDF returned a static file delivered to a static location. To me, the static location is not an issue, but the static name IS a problem. Good news is that I found the place where I can modify the returned filename to the API (I created a cloud service to alter the pdf_Url dynamically).
Richard,
It is a static file (meaning it cannot be modified) and it is returned to a static location (a folder set in the API service properties), however the name of the file is set as one of the parameters for the API call.
Regards,
Mark