Xpage with Agent LotusScript

Hello there

I have a LotusScript agent which change the value of the fields of a document

After call that agent in JS ServerSide I need to get the document with the new values

The agent change the values but when I try to get the new values in JS serverside it dont succeed.

Thank you in advance

Nina

Subject: Possible solution

Hi

I had the same issue where I was trying to use legacy LS code to perform the bulk of the work.

It turned out that I needed to recycle the in memory notesDocument and the retrieve it back from the database, after the LS has worked on it.

This is quiet normal and you DO NOT need to create a temporary document to achieve this. For me I had the following constraints:

With Domino 8.5.2 onwards there is a function agent.runWithDocumentContext(doc) that will perform this, but the LS agent must have ‘Run as web user’ enabled.

In my case, the web user didn’t have/ will never have the sufficient authority access the relevant databases.

Domino will not allow the programmer to recycle a notesDocument based on the current database source. So I had to create a temporary notesdocument on the database, copy across all the fields, save it, and then pass that document to the agent top process. After the agent has processed the temporary document, my SSJS code retrieves the document back from the database, copy all the fields (now modified by the LS agent) back to the in memory document; then remove the temporary document.

var doc:NotesDocument = null;

var docToProcess:NotesDocument = null;

var ag:NotesAgent = null;

try{

doc = document1.getDocument(true);

//Where document1 is the XSPDocument (currentDocument).

doc.save();



//This (below) is only valid if you are attemting to process the in Memory Notes XSp document, as Domino will not let you recycle the backend NotesDocument.  

//So we must go through the process of creating a temorary document  then process that document.

docToProcess = database.createDocument();

doc.copyAllItems(docToProcess, true);

docToProcess.save();

var docUNID:String = docToProcess.getUniversalID();

var docNoteID:String = docToProcess.getNoteID();

	

ag = database.getAgent("(agTest)"); 

if(ag)

{

	ag.runOnServer(docNoteID);

	docToProcess.recycle();

	docToProcess = database.getDocumentByUNID(docUNID);

	

	if(docToProcess)

	{

		docToProcess.copyAllItems(doc, true);

		doc.save();

		print(doc.getItemValueString("name"));

		// here it will show the new value

		docToProcess.remove(true);

		docToProcess.recycle();

		// the finally in the try/catch will removed the temp document, or you can do it here.

		return true;

	}

}else

{

	//Do some error handling here.

	return false; 

	//finally in the try/catch will recycle all the domino objects used.

}	

/* agTest is in lotuscript and change the value of field "name" of a document */

}catch(e)

{

}finally

{

if(docToProcess)

{

	docToProcess.remove(true);

	docToProcess.recycle();

}

if(ag) ag.recycle();

if(doc) doc.recycle();

}

Subject: Some source code would be helpful…

…and also if you would explain what exactly you mean by “doesn’t succeed.”

Subject: Xpage with Agent LotusScript

Hello Andre

this is the snippet:

var ag=database.getAgent(“(agTest)”);

/* agTest is in lotuscript and change the value of field “name” of a document */

ag.runOnServer(document.getNoteID());

print(document.getItemValueString(“name”));

// here it doesn’t show the new value

Thank you :slight_smile:

Subject: I would…

Rewrite the agent in SSJS if possible and then update the document on the front end ui, or you could do a

Doc1 = document1.getDocucment()

Then do whatever your agent does

Doc1.save(treu, true)

Then document1.getItemValue…

Subject: Calling LS agent from XPages

If you’re calling the agent from the postSaveDocument event then using the runOnServer method is correct.

var agent= database.getAgent(“”);

agent.runOnServer(.getNoteID());

What you may need to do after the agent returns to get the updated values is:

.getDocument(true);

to force the updates to be applied to the datasource.

Subject: This will never work…

  • R8.5.1 doesn’t support legacy code in this fashion, in any meaningful manner. Doing getDocument will not help, at least it didn’t when I tried it months ago. It’s plausible FP3 may fix that and I don’t know about it.

  • You can do this kludge in your SSJS

  1. Run your agent.

  2. Instantiate a View that contains the data on your document that you wish to fetch.

  3. Use known data from the document (unid, for instance) to fetch the column of data from that View.

  • This will work.

HOWEVER.

  • My (extensively unpleasant) experience with legacy Agents and R-Current XPages is AVOID LIKE ANTHRAX. Even if you are able to pull data using the kludge above, at some random point in the future your XPages will exhibit other random, un-reproducable errors relating to the collision between the XSP command processor’s in-memory copy of the document, and the back-end document as modified by the legacy Agent. Because they are random and un-reproducable, Lotus support will fail you utterly, for as long as you will let them string you along.

  • I got this to work by using an out-of-band AJAX call to the legacy Agent. In a nutshell, this calls the Agent after the current XPage has completely unloaded, thereby avoiding the data conflict with the XSP command processor. If needed the CSJS which calls the AJAX reloads the page it just left, but in my particular case this return is the exception and not the rule, so nothing would normally be lost by this hack.

  • If this sounds too complex I’d wait for R8.5.2 and hope their new in-memory do-dad will actually work. If it does it will avoid the entire XSP/LotusScript collision and things will work they way they SHOULD have when R8.5.0 was released.

Good luck…

Subject: Whatever else you end up doing…

If you use a different process to modify a document that you’ve already have in memory, you will need to recycle the object and reload it for the change to register.

Can’t you use a script library for that these days?

Subject: Ideally we’d all be using SSJS anyway, but since you can’t use it for scheduled agents…

Subject: Perhaps I’m doing it wrong…

I tend to do the following:

  • Call the LotusScript Agent via a Java URLConnection, passing it the UNID of the document/documents I want to update.

  • Write the LotusScript Agent to look for a QueryString Parameter (UNID=).

  • Once the Agent is called, I refresh the given display.

The reason I run the LotusScript Agent by passing it a UNID vs. the direct RunOnServer and pass it the target NoteID is simple… I’m multi-purposing the Agent so that it’s available not only to Lotus Notes Domino but also to other technology platforms that can initiate an HTTP Request.

Mind you, I’ve actually moved away from even this practice with the advent of XPage XAgents, where I use the same technique discussed with the LS-based Agents, but my XPage XAgents use SSJS Library methods to perform the changes… and thus making the methods available bot to the XAgent and other XPages.

HTH,

-Chris

Subject: You need 8.5.2

And dont runonserver,its already on the server :wink: