(Continued from Part 1.This and the other posts in this series is material I’ve written for Programming Windows Store Apps in HTML, CSS, and JavaScript, Second Edition.)

By itself, an iterator only has methods to go through the collection in one direction (IIterable.first returns an IIterator whose only methods are getMany and moveNext). A vector is a more capable variant (IVector derives from IIterable) that adds random-access methods (getAt and indexOf) and methods to modify the collection (append, clear, insertAt, removeAt, removeAtEnd, replaceAll, and setAt). A vector can also report its size. [Footnote: The IObservableVector interface in Windows.Foundations.Collections exists for other languages and is not ever seen in JavaScript.]

Because a vector is a type of iterator, you can also just treat it as a JavaScript array—a vector that you obtain from some WinRT API, that is, will have methods like forEach and splice as you’d expect. The one caveat here is that if you inspect a vector in Visual Studio’s debugger (as when you hover over a variable), you’ll only see its IVector members.

Vectors basically exist to help marshal changes to the collection between the JavaScript environment and WinRT. This is why IIterable is used as arguments to WinRT APIs (the input array is effectively read-only), whereas IVector is used as an output type, either for the return value of a synchronous API or for the results of an asynchronous API. For example, the readLinesAsync methods of the FileIO and PathIO methods in Windows.Storage provide results as a vector.

Within WinRT you’ll most often encounter vectors with a read-write collection property on some object. For example, the Windows.UI.Popups.MessageDialog object has a commands property of type IVector<IUICommand>, which translates into JavaScript simply as an array of UICommand objects. Because the collection can be modified by either the app or the WinRT API, a vector is used to marshal those changes across the boundary.

In quite a number of cases—properties and methods alike—the collection involved is read-only but still needs to support random-access characteristics. For this we have the vector view (IVectorView also derives from IIterable), which doesn’t have the vector’s modification methods. To give a few examples, a vector view of ConnectionProfile objects is what you get back from NetworkInformation.getConnectionProfiles. Similarly, StorageFolder.getFilesAsync provides a vector view of StorageFile objects. The user’s preferred languages in the Windows.System.UserProfile.GlobalizationPreferences object is a vector view of strings. And you can always get a read-only view for any given read-write vector through the latter’s getView method.

Now because a vector is just a more capable iterator, guess what? You can just treat a vector like an array. For example, the Folder enumeration sample uses StorageFolder.getFilesAsync and getItemsAsync to list the contents of in your various media libraries, using forEach to iterate the array that those APIs produce. Using that example, here’s what I meant earlier that Visual Studio only shows the IVector members—the items from getItemsAsync doesn’t show array methods but we can clearly call forEach (circled):

Vector methods


(This and the other posts in this series is material I’ve written for Programming Windows Store Apps in HTML, CSS, and JavaScript, Second Edition)

All of the WinRT collection types are found in the Windows.Foundation.Collections namespace. What you’ll notice immediately upon perusing the namespace is that it actually contains only one concrete class, PropertySet, and is otherwise its chock full of “interfaces” with curious names like IIterable<T>, IMapView<K, V>, and IVectorView<T>.

If you’ve at least fiddled with.NET languages like C# in your development career, you probably already know what the I and <T> business is all about because you get to type it our all the time. For the rest of you, it probably makes you appreciate the simplicity of JavaScript! In any case, let me explain a little more.

An interface, first of all, is an abstract definition of a group of related methods and properties. Interfaces in and of themselves have no implementation, so they’re sometimes referred to as abstract or virtual types. They simply describe a way to interact with some object that “implements” the interface, regardless of what else the object might do. Many objects, in fact, implement multiple interfaces. So anytime you see an I in front of some identifier, it’s just a shorthand for a group of members with some well-defined behavior.

[Footnote: There are actually all kinds of interfaces floating around the WinRT API. When working in JavaScript, however, you rarely bump into them because the language doesn’t have a formal construct for them. For example, a page control technically implements the WinJS.UI.Pages.IPageControlMembers interface, but you never see a direct reference to that name. Instead, you simply include its methods among the instance members of your page class. In contrast, when creating classes in other languages like C# you explicitly list an interface as an abstract base class to inherit its methods.]

With collections in particular, it’s convenient to talk about the collection’s behavior independently from the particular object type that the collection contains. That is, whether you have an array of strings, integers, floats, or other complex objects, you still use the same methods to manipulate the array and the same properties like length are always there. The <T> shorthand is thus a way of saying “of type T” or “of whatever type the collection contains.” It certainly saves the documentation writers from having to copy and paste the same text into dozens of separate pages and do a search-and-replace on the data type! Of course, you’ll never encounter an abstract collection interface directly—in every instance you’ll see a concrete type in place of <T>. IVector<String>, for instance, denotes a vector of strings: you navigate the collection through the methods of IVector, and the items in the collection are of type String.

In a few cases you’ll see <K> and <K, V> where K means key and V means value, both of which can also be of some arbitrary type. Again, it’s just a shorthand that enabled us to talk about the behavior of the collection without getting caught up in the details of whatever object type it contains.

So that’s the syntactical sugar—let’s now look at different WinRT collections.

Iterators

An iterator is the most basic form of a collection and one that maps directly to a simple array in JavaScript. The two iterator interfaces in WinRT are IIterable<T> and IIterator<T>, you’ll never work with these directly in JavaScript. For one thing, a JavaScript array (containing objects of any type) can be used wherever a WinRT API calls for an IIterable. Second, when a WinRT APIs produces an iterator as a result, you can pretty much treat it as an array. (There are, in fact, no WinRT APIs available from JavaScript that directly produce a plain iterator; they produce vectors and maps that derive from IIterable and thus have those methods.)

In short, iterators are transparent from the JavaScript point of view, so when you see IIterable in the documentation for an API, just thing “array.” For example, the first argument to BackgroundDownloader.requestUnconstrainedDownloadsAsync (see Chapter 4 of the second edition) is documented as an IIterable<DownloadOperation>. In JavaScript this just means an array of DownloadOperation objects; the JavaScript projection layer will make sure that the array is translated into an IIterable suitable for WinRT.

Similarly, a number of APIs in the Windows.Storage.FileIO and PathIO classes, such as appendLinesAsync and writeLinesAsync all take arguments of type IIterable<String>, which to us just means an array of strings.

Occasionally you’ll run into an API like ImageProperties.savePropertiesAsync (in Windows.Storage.FileProperties) that takes an argument of type IIterable<IKeyValuePair>, which forces us to pause and ask just what we’re supposed to do with an collection interface of another interface! (IKeyValuePair<K, V> is also in Windows.Foundation.Collections.) Fortunately, the JavaScript projection layer translates IIterable<IKeyValuePair> into the concrete Windows.Foundation.Collections.PropertySet class, which can be easily addressed as an array with named members, as we’ll in part 3.