SPServices GetListItems returning field values as "undefined" - sharepoint

I ran across a problem for which I found no documented solution, but inadvertently found the solution myself. So I wanted to document this here for others who may encounter the same problem.
I was using a CAML query within SPServices to retrieve list items, then referencing "ows_{fieldname}" as usual to retrieve the field value for each list item. The field value was reported as "undefined" for all items. I quintuple-checked that I was specifying the proper name of the field and that my query was properly constructed.
I eventually discovered that the fields I was trying to reference were not displayed in the default view of the list. As soon as I changed the list properties to include the fields in the default view, the proper field values were returned within my javascript.
I don't know how much of Sharepoint's underpinnings work, but I was very surprised at my finding because it implies that the SPServices GetListItems method gets its data from the list's default view, not the actual underlying list. I realize I could be wrong in this interpretation, but I imagine others could run into this same problem.

The default, although unreliable, way GetListItems works is that it's suppose to returns all fields displayed on the default list view if you don't specify ViewFields on input. This is unreliable. Although you got it working - now - someone could come along later and change the default view thus breaking your sweet customization. Bummer. :)
I suggest always listing the ViewFields you are interested in on the GetListItems method. This ensures that your will get them if they are set. That's right. You could still get rows with an undefined field. This happens mostly on fields of type Lookup that are not set on a row.
Hope this helps you understand what is going on. Over the years I have created my own wrappers around SPServices to ensure I get back a reference to all fields requested, even if they are not in the response by Sharepoint.

When using SPServices' GetListItems method, be sure that any fields that you reference from the list are included in the list's default view, otherwise an undefined value will be returned.

Related

Retrieving column values in filtered xpages view

I have a view defined on an xpage. I also have several filters (based on the columns) that the user can select and combine to filter the results in the view. I generate a query string based on this that I construct in dominoView.search (doing a complete refresh). What I would like to do is get the results of the search so that I can then update some counts displayed elsewhere on the page. I'm having a hard time figuring out where I can perform this logic, though. I'm trying to use view.getAllEntries() and then iterating over the collection. Sometimes it seems like it works, but other times I seem to be getting the unfiltered view. Someone suggested I explicitly call view.FTSearch inside one of the events (beforePageLoad?) and immediately after do my getAllEntries call, saving the results in viewScope, but I get an "Error while browses Notes view" runtime error when I try to do that. Any pointers? TIA!
EDIT: After studying the xpages lifecycle a bit (which is still a little confusing), I think I can fine-tune my question. This is my first stackoverflow question, so I hope this is okay to do and productive....
As I described, I have a dominoView defined on my xpage. A repeat iterates over the rows of the view, displaying certain fields from the documents. If I define a query in the search property, then the repeat correctly displays the reduced set of documents rather than the complete set. (The query is computed in the search property via SSJS from some variables defined in the viewScope in a combobox's eventHandler.) However, if I try to access the current entries in the view inside of the repeat's rendered section (with SSJS) using myView.getAllEntries (where myView is what's defined as the "value" of the repeat), I am still getting all of the documents, even if a query has been done. It seems like at that point, the view variable has already had its search applied (since the repeat works), so why the differing results? Is there another way to access the view's rows? To complicate this further, this is just a simple experiment that might clarify the problem; as I indicated earlier, I don't actually want to access the view data within the repeat, I want to access it in the rendered or value sections of some comboboxes defined before the repeat in the xpage file.
I hope that makes more sense now....
EDIT #2: I forgot to add that if I manually call FTSearch (or FTSearchSorted) before calling myView.getAllEntries, then I think I can make this work. It just seems unnecessary to have to do that in addition to the view's built-in search.
From what I get you want to iterate over the entries in a view that before has been filtered, i.e. whose resulting entry collection is smaller than the the view itself.
What I don't get (yet) is what you want to do with the result, or what you're axpecting to get from the iteration over your filtered view (you're mentioning some counts to be displayed somewhere else).
Probably a good way is to use the view's .getAllEntriesByKey method which returns a NotesViewEntryCollection object which then can be used for your iteration.
Don't forget to recycle the resulting NotesViewEntry objects; reason for this has been explained several times here at stackoverflow.

session.evaluate and notesxspdocument

I have question regarding session.evaluate in SSJS. In a keyword document I have some #formula stored which does some conversion of data. Lets say this is would be:
#left(fieldname;2)
If the fieldname contained 'hello' this would result in 'he'. Nothing to fancy here. Now I would like to use this in an xpage.
I wrote a function called executeFormula(doc). I call this function from an action on a xpage. This xpage contains 1 notes document datasource. The function call is
executeFormula(datasource.getDocument(true))
Now for some reason the #formula is never calculated correctly. Do I need to save the document first before I can use session.evaluate(kwFormula,doc) or is the #formula wrong in some way?
p.s. I forgot to mention that this code is working inside a customvalidator
Without seeing the code for the executeFormula(doc) function it is very difficult to know exactly how session.evaluate is being called.
I would suggest taking the function out of the equasion for the moment and create a simple test page with the document source and a simple computed field with the session.evaluate in it so that you can see the result. Given your examples above the computed field would be something along the lines of
session.evaluate("#Left(fieldname;2)",xspDoc.getDocument(true));
Once you get acceptable results back then you can move it into your function and verify that it is working there also.
Don't forget that session.evaluate returns a vector so you may beed to do a .getFirstElement() on the returned value if it is not null.
If you're using it in a custom validator, the values posted from the browser/client haven't updated the data model (in your case, the document) yet. This happens after validation is successful.
I imagine it might work for some fields (e.g. fields that are updated after a successful refresh, or stored fields in an existing document).
Actually no need of mentioning the document, eg:- session.evaluate("#username") is enough.
For yours session.evaluate("#left('hello';2)") will work.,

Sharepoint Extenal List and Custom Field Types

I have an odd issue.
I have client that wants a sharepoint list what is populated from a WCFService. That part is working quite well.
I have a bdcmodel that is mapping the WCF data and I can create an external list from the bdcmodel as well so that is working fine.
The issue I have is that one of the properties in the model is actually a collection of entities called Attributes. The objects in this collection simply have 2 properties Name and Value so really they are just a key value pair.
The client wants to see the list of attributes of the parent entity in the external list. So there would be an Attributes column and within that column would be the list of attributes for each parent object.
Is there even a way to do this? I am looking into Custom Field Types, but it seems like these are really intended to be singular values.
How would I create a list within and external list?
Any help anyone can give would be great even if its just to tell me that there really isn't a stable way to do this so I can go back to the client and tell them we will need to build a custom list to support this because the OOB external list and custom fields and custom field types won't support this kind of nested listing.
I decided to set up the custom field as a string and when I get my collection in from the BdcModel I am serializing it to JSON and then passing it to the field. When the field is viewed in display, edit or new I have overridden the FieldRenderingControl and I am tiling the collection out that way.

NSArrayController that is sorted and unique (no duplicates) for use in a pop-up in a core-data app

I have core data app with an entity OBSERVATION that has as one of its attributes DEALNAME.
I want to reference through Interface Builder or by making custom modifications to an NSArrayController a list of unique sorted dealnames so that I can use them in a pop-up.
I have attempted to use #distinctUnionOfSets (and #distinctUnionOfArrays) but am unable to locate the proper key sequence.
I can sort the ArrayController by providing a sort descriptor, but do not know how to eliminate duplicates.
Are the #distinct... keys the right methodology? It would seem to provide the easiest way to optimize the use of IB.
Is there a predicate form for removing duplicates?
Or do I need to use my custom controller to extract an NSSet of the specific dealnames, put them back in an array and sort it and reference the custom array from IB?
Any help would be appreciated. I am astounded that other have not tried to create a sorted-unique pop-up in tableviews.
You need to take a look at -[NSFetchRequest returnsDistinctResults]. That is the level you need to be handling the uniquing of data.
Although I do not have a definitive answer for you, I think there are two ways you can go about it.
The way you already started. You need to bind the contents array of the PopUp button, not just against the arrayController.arrangedObjects, but continue on the path and somehow filter only objects with distinct "DealName"s. This means - the arrayController presents ALL the entities (and may sort them for you) but the PopUp button will have its contents filter via some sophisticated binding to the array controller.
Make your filtering at the ArrayController level (as suggested in another answer here). Here it depends how you set up the array controller. If It is set up to use an "Entity" (vs. "Class") which means the array controller will fetch CoreData entities directly - you can modify its "Fetch" to only bring a subset of the "OBSERVATION" entities with distinct values of "DEALNAME". I don't know how to control WHICH entities are filtered out in this case. Otherwise, you can setup the arrayController to work with "Class" objects, and then you can fetch the entities yourself (in code) and populate the arrayController programmatically, with just the entities you like.
In the second option, the Popup button should be bound normally to the arrayController's arrangedObjects.

Difference between FieldLinks and Field in Sharepoint

I'm in the middle of trying to copy a custom content type from one web to another. I've googled around and found some examples that use FieldLinks and Fields. I'm kind of lost as to which one to use, since when I get the FieldLinks from my source web, I get 3 fields; while retrieving from Fields only returned me 2 fields... the custom field is missing. I'm pretty darn sure that I've added the fields at the proper level since I did it via the interface. But when retrieving it using code... the numbers just don't add up.
So besides from that strange problem, I want to know what is the difference between FieldLinks and Fields, and when dealing with them in Content Types (programmatically) which one should I use?
Thanks.
SPFields are fields themselves, while SPFieldLinks are references to the fields. This is a good read that will explain things in detail. In general practice, it is safer to use SPFieldLinks when you are working on the actual content type definition. However, I'll give a quick summary here.
Lists and Webs contain the actual fields with field data. A content type, on the other hand, only holds Field Reference, which simply points at the corresponding field in the list or web. This gets a bit confusing, because content types have both an SPFieldLinkCollection and an SPFieldCollection.
The SPFieldLinkCollection is used in the actual definition of the content type, and is what you would want to use in your situation of copying a content type from one web to another. SPFieldLinks correspond to the actual elements in the XML Schema for a content type.
Comparatively, when you call on a content type's SPFieldCollection and retrieve a Field from it, what is actually happening is that the content type is checking the corresponding field reference, and then looking up in the list/web to get the actual field. Basically, think of the SPFieldCollection in the same way a lookup works: it is worthless without both the lookup value and the lookup source.

Resources