In this post (), Julie Kadashevich says that one should not use NotesAgent.runOnServer() from the web, that this maps internally to NotesAgent.run() because the (server side) code is already on the server. The resolution leading from this thread did in fact involve using run() and not runOnServer() to execute the Agent, and given her explanation that certainly follows.
This leads me to a quandry, however, because run() does not allow a value to be returned, where runOnServer() does. I was going to (attempt to) use that return value in the postSaveDocument event of my XPage to change where it redirected, since my experimentation indicates that the LS Agent can not load a XPage using the familar “Print [url]”. Now it seems changing the redirect on the XPage is not possible.
I pretty much have to use a LotusScript Agent. If I could use a SSJS library I would be doing that and all would be well. Unless there is a JS2LS bridge I don’t know about? (grin)
I’d like to ask for ideas on how to get a return value from a LotusScript Agent invoked on a XPage. It doesn’t have to be fancy. True/false will suffice. An int would be better. A string would be fantastic.
We have a number of agents in classic web development and Notes Client that need to run under a specific authority. What we tend to do is create a control document as an intermediary. We then pass that control document to arunOnServer agent, for it to update with success/failure/error messages. After the runOnServer agent we then get the outcome from the control document, and flag for deletion.
In theory this should work for XPages design and was already intended as my first approach when I needed to run LS from XPages.
Subject: Thanks Paul! Still looking for suggestions…
This is what I’m doing, only using the actual document instead of a control document. Since the document is opened on the XPage, and it appears to be impossible to pass data back without saving it, I’ve added fields to the document to manage the Agent interaction. If it fails muster (which can only be determined by the Agent), then the fields will capture that failure.
Sadly this does not work. The updates on the document do not appear in postSaveDocument after the Agent runs. I suspect this is because the current document on the XPage, the one I send as the Agent parameter document, is still cached. Even though I re-acquire it, the XPage processor has a copy of it, and it points to that copy. I’m not sure if I can delete currentDocument in postSaveDocument, or if I can, what that will do the XPage processor.
I suspect you’re right that it’s getting the in-memory current document rather than the version from the disk. I guess it’s kind of similar to how in the client you need to do a uidoc.Refresh after changing the back-end NotesDocument properties. But of course in XPages don’t currently have access to the front-end classes to do a Refresh.
I seem to remember reading something about problems getting the current document from disk rather than cache, but I’m afraid I can’t remember where I saw it and can’t manage to track it down. My gut instincts say using a separate control document is most likely to work, because the XPages processor doesn’t have a handle on it. If I had to do minimum risk, I would get the control document again after the agent has run using database.getDocumentByUNID - if this doesn’t have the values saved by the agent, nothing will.
In the code running after the agent has been triggered I would also try to capture, if possible, the last modified time of the control document and current time, to check if the code is waiting until after the agent has run or is running concurrently. That’s another risk I would envisage as a possibility, that it calls agent.run and goes onto the next line without waiting for the agent to complete. If that’s happening, you’ll definitely need an alternative approach.
You are correct that the document is cached and you you need to delete the reference before using it.This was the case even without Xpages. You can see a simple example in this article IBM Developer
and compare it to your code.
The general problem you are dealing withI is being investigated (passing a document without saving it). Stay tuned.
Found this thread again after searching for another problem, so I figured I’d put in what seems to be working:
In postOpenDocument, update any number of fields on currentDocument. I only do one.
Call currentDocument.save();
Invoke the “webqueryopen” LotusScript Agent with currentDocument as the parameterDocument. Be sure to save the parameterDocument in the Agent.
Use @DbLookup() to fetch data from a View containing currentDocument after the Agent returns. Any number of fields may be fetched in this manner.
Use this data to whatever in postOpenDocument, after the Agent has run.
Step 4 was discovered by Lotus via PMR, and it seems to work fine. The only significant drawback I’ve found to this approach is that Form, XPage, and anything else related to saving must be configured to overwrite conflicts, or the Agent will create a conflict when it saves the parameterDocument. This save has not, to date, caused any noticeable problems on the XPage itself.
Thanks for your thoughts!..
EDIT: Something that’s not obvious from the above: Deleting the document used as the parameterDocument to the Agent, the one the XPage is bound to, does not work. While the delete doesn’t throw an error or fail in any obvious manner, it does in fact fail to delete, since after the Agent is run the fields updated on it are not changed on the Xpages currentDocument. The only way to get the updated data is using @DbLookup as described … for some reason Views have the latest data, even from Agent saves, where the cached XPage document does not.
I don’t believe this is the pOD code continuing to run, because it doesn’t continue when agent.run() is called. It blocks until something comes back, or that’s what it seems to do, otherwise the @DbLookup that runs the very next statement would never acquire the new data, but it consistently does so.
Ultimately, however, this caused other problems, because other data changed by the Agent would not appear on the document being loaded, so it’s actually nothing like WQO at all, where data applied to the document does appear on the web page. The entire thing was converted to AJAX that’s called on the link that loads the document, completely removing any and all pOD usage, and ensuring the page that loads reflects the changes made by the Agent.