FORUM PLAN UPDATE
Date revision: This forum will remain open to new posts and responses until December 1, 2018. (After that date, you will still be able to view and search the forum.) Also, we're taking a second look at the best place to host future conversation. For now, keep using this forum, and stay tuned for more news.



Aug 6, 2014, 10:31 PM
110 Posts

When to actually use "return"?

  • Category: Server Side JavaScript
  • Platform: Windows
  • Release: 9.0.1
  • Role: Developer
  • Tags: return
  • Replies: 3

When to actually use "return" in SSJS? I'm currently enhancing an XPages application built by another developer 2 years back. Both of us are developing classic Notes application and don't know anything about javascript back then thus even if I asked him now, the answer will be "the help files says so".

Anyway, I've encountered 4 examples that made me confuse:

1 if (a == 2) {
    "the value of a is 2";
} else {
    "the value of a is not 2";
}
Usually used/found it in computed fields.
2 if (a == 2) {
    return "the value of a is 2";
} else {
    return "the value of a is not 2";
}
Usually used/found it in computed fields.
3 if (doc !== null) {
    doc.replaceItemValue("testField", "2");
} else {
    doc2.replaceItemValue("testField", "3");
}
Usually used/found it in long script (onClick etc). Could have some code before/after this code.
4 if (doc !== null) {
    doc.replaceItemValue("testField", "2");
    return;
} else {
    doc2.replaceItemValue("testField", "3");
    return;
}
Found it in long script (onClick etc). Could have some code before/after this code.

I myself had only used example 1 - 3 interchangeably and had no problem with those. That said developer however had used example 4 in his code (if I may say, a lot). Searching for "getDocumentByKey (NotesView - JavaScript" in the help files shows something similar to example 4.

I know it seems like a basic thing to most people but it makes it difficult when I'm reading his code since I'm not sure what it meant. Maybe he's right and I'm wrong or vice versa, I'm not sure. I just want to be consistent. I've searched other part of the web (MDN etc) but I want to limit the scope to at least how it should be used in XPages SSJS and the best practice. Thanks.

Aug 7, 2014, 4:14 PM
589 Posts
hmm

I think the key is as consistent as possible above all else..

Personally I TRY to use them often but only when it makes sense...  for instance I just did this:

 

<xp:this.styleClass><![CDATA[#{javascript:return "row " + controller.getManifestRowStyle(manifestData);}]]></xp:this.styleClass>

So that has a return which arguable would would fine without it.

On the same page I did this:

<xp:eventHandler

event="onclick"

submit="true"

refreshMode="partial"

refreshId="aPanelManifestInner">

<xp:this.action><![CDATA[#{javascript:viewScope.put("CurrentManifest", manifestData);}]]></xp:this.action>

</xp:eventHandler>

 

So I didn't add an additional return at the end for an action.  I guess I only really try and use it in SSJS if I am actually returning to a calling value. Though I am doing less and less SSJS these days...

 

I'm iffy on example 4 in your post.  If the code hits a return, it's typlically "done" with that function.  So if you did have code after that if statement I'm pretty sure it's not going to run at all.  

 

Interesting question!!!

 

Dave

 

Aug 7, 2014, 6:37 PM
453 Posts
Welcome to the club

Been a N/D developer since 1995, and only got into XPages about a year ago. So I have an understanding of you pain.

From a practical side (and I do not count myself as an expert) all 4 examples should work. I tend to use the return when there is code after my comparison then use it with a break; Other wise I tend to only use the return when the code might not be obvious. In all 4 of your examples it is pretty obvious that the return is either or. But when the code gets more complex the return & break would be my suggestion so that next time you or some other developer looks at the code the flow is obvious.

If I had this sort of code I would definitely use the return

if (something == 1){

//do  a few lines of code

return Some Value or null

break;

}else{

//whole bunch of code with multiple if else etc

return Some Value or null;

break

}

in this case I would definitely use the return and break because just looking at the code lets you know when you are leaving Dodge.

Also, (and I get nothing for this from Howard) http://TLCC.com has some really good on-line courses that can really ease the pain and help the climb up the learning curve, as well as some good best practices.

Aug 8, 2014, 10:54 AM
453 Posts
Baxxter - One other Important Thing RECYCLE

If you are coming from a traditional N/D development background then you are used to declaring Notes Objects and then forgetting about them, but in SSJS and JAVA you need to recycle recycle recycle. This is a topic that there are bits and pieces of information around in various places but when I started I was not really aware of the issue until my server would get slower and slower until it finally I would restart it and come back up to speed. The issue was the accumulation of unrecycled Notes Objects. You example 3 is a case in point where doc would end up as stranded Notes Object. So I have developed a style that works for me and I put it here for what it is worth. Just wish I would have seen this earlier in the process as I would have saved me a lot of grief.

This is probably old hat and obvious to those who have been developing using SSJS and JAVA but it sure is not obvious from IBMs documentation and it is something that needs to be shouted from the roof tops, because failure to do something like this will cause your app to cause a server crash at some point. I know I did it! Many Times! Before I stumbled across the answer!
Anyway, hope this helps someone who is starting XPages development, and if someone has a better idea I'd love to see it.

try{
    var vw:NotesView = database.getView("SomeView");
    var dc:NoteDocumentCollection = vw.getAllDocumentsByKey("Some Key")
    var doc:NotesDocument = dc.getFirstDocument();
    var tDoc:NotesDocument = null
    while (doc != null) {
        tDoc = dc.getNextDocument(doc);
        //do some stuff
        doc.recycle();
        doc = tDoc
    }
}catch(e){
    Utils.sysOut("Error in my Code " + e.toString());
}finally{
    try{
        Utils.recycleObjects([tDoc,doc,dc,vw]);
    }catch(e){
        /*this will happen if you try to recycle an Object Variable that has not been defined
        either by an error in the code that causes the first catch as if there was no
        view by the name "SomeView" vw, dc tDoc and doc would be undefined
        or
        if your could completes the try but recycle fails because you try to recycle say doc2
        */
        Utils.sysOut("recycleObject failed " + e.toString());
    }
}

I have created a managed Bean that contains the code for sysOut and recycleObjects that I have 'recycled' from some where and here is the code for that:

ackage ca.wfsystems.core;

import lotus.domino.*;

public class Utils {

    public static void recycleObjects(Object... args) {
        for (Object o : args) {
            if (o != null) {
                if (o instanceof Base) {
                    try {
                        ((Base) o).recycle();
                    } catch (Throwable t) {
                        // recycle failed probably because the object was not present - so what?
                    }
                }
            }
        }
    } //end recycleObjects
    
    public static void sysOut(Object msg){
        System.out.println(msg.toString());
    } //end sysOut
}// End Class

 


FORUM PLAN UPDATE
Date revision: This forum will remain open to new posts and responses until December 1, 2018. (After that date, you will still be able to view and search the forum.) Also, we're taking a second look at the best place to host future conversation. For now, keep using this forum, and stay tuned for more news.