WebViewer Version: 11.7.1
Do you have an issue with a specific file(s)? No
Can you reproduce using one of our samples or online demos? No
Are you using the WebViewer server? Yes
Does the issue only happen on certain browsers? No
Is your issue related to a front-end framework? No
Is your issue related to annotations? Yes
Please give a brief summary of your issue:
We are facing an issue while implementing a “Apply Stamp to All Pages” feature using Apryse WebViewer, and we would like your guidance on the correct approach.
Please describe your issue and provide steps to reproduce it:
We are facing an issue while implementing a “Apply Stamp to All Pages” feature using Apryse WebViewer, and we would like your guidance on the correct approach.
Our current implementation
- A user places a Rubber Stamp on the current page.
- On “Apply to All Pages”, we:
- Clone the stamp for all other pages using
annotationManager.getAnnotationCopy() - Add the cloned annotations programmatically using
annotationManager.addAnnotation()/addAnnotations() - Export XFDF per annotation using
annotationManager.exportAnnotations({ annotationList }) - Save all stamps to the backend in one bulk API call
- During bulk stamping, we guard the
annotationChangedevent using a flag (isBulkStamping) to avoid saving intermediate events.
The problem
After bulk stamping is completed, when the user later adds or modifies any new annotation, we see duplicate processing / saving of previously created stamp annotations.
We traced this behavior to the following logic inside our annotationChanged listener (this part cannot be removed due to existing architecture dependencies):
const xfdfCommands = await annotationManager.exportAnnotationCommand();
for (const annot of annots) {
if (measurementTools.includes(annot.ToolName)) {
annot.removeCustomAppearance();
await annotationManager.redrawAnnotation(annot);
}
PartialApryse.ProcessAnnotation(annot, xfdfCommands, action);
}
PartialApryse.SaveDocumentAnnotations();
Key observations:
annotsonly contains the annotations related to the current eventexportAnnotationCommand()returns global command history, including commands related to previously added bulk stamps- When a new annotation is added later, the global command export appears to include past stamp commands again, leading to duplicate processing/saving on our side
What we would like to understand
- Is
exportAnnotationCommand()expected to return all pending/global commands, even for annotations that are not part of the currentannotationChangedevent? - Is there a recommended way to:
- Scope
exportAnnotationCommand()only to the annotations involved in the current event? - Or clear/reset command history after a bulk operation?
- For bulk annotation workflows, is Apryse’s recommended pattern:
- To rely only on
exportAnnotations({ annotationList })for delta-based saving? - Or is there a supported way to safely combine
annotationChangedwithexportAnnotationCommand()without reprocessing old annotations?
- Are there any best practices or flags we should use when annotations are added programmatically (bulk add) to avoid them being reprocessed on subsequent user actions?
We want to ensure we are following the correct and supported Apryse workflow, especially for bulk annotation scenarios, without introducing duplicate saves or unintended side effects.
Code for adding stamp to All Pages:
if (selectedOption === 'all') {
const bulkRequest = [];
isBulkStamping = true;
for (let pageNumber = 1; pageNumber <= totalPages; pageNumber++) {
if (pageNumber === currentPage) {
const currentStampXfdf = await annotationManager.exportAnnotations({
annotationList: [lastStamp],
action: 'add'
});
bulkRequest.push({
caseId: $('#Id').val(),
contentItemId: $('#ContentItemId').text().trim(),
annotData: currentStampXfdf,
annotType: lastStamp.ToolName,
annotId: lastStamp.Id,
pageNumber: pageNumber,
currentUserId: userID,
status: 'None',
});
continue;
};
const clone = annotationManager.getAnnotationCopy(lastStamp);
clone.PageNumber = pageNumber;
annotationManager.addAnnotation(clone);
annotationManager.redrawAnnotation(clone);
const xfdf = await annotationManager.exportAnnotations({
annotationList: [clone],
action: 'add'
});
bulkRequest.push({
caseId: $('#Id').val(),
contentItemId: $('#ContentItemId').text().trim(),
annotData: xfdf,
annotType: clone.ToolName,
annotId: clone.Id,
pageNumber: pageNumber,
currentUserId: userID,
status: 'None',
});
}
PartialApryse.ApplyBulkStamp(bulkRequest);
isBulkStamping = false;
}
Please provide a link to a minimal sample where the issue is reproducible: