Short answer
Use _.invoke instead of _.pluck
See this sample script .
Long answer
_.pluck(list, propertyName) works as documented:
A convenient version of perhaps the most common use case for a map: retrieving a list of property values.
Or, as best deduced on lodash docs: _.pluck(collection, path)
Gets the value of the path property of all elements in the collection.
So if you do this:
_.pluck(myArray(), "id")
what you get is an array with all id . And all these id are observable, as in the objects of the original array
But you can use _.invoke(list, methodName, *arguments) , which, as described:
Calls a method named MethodName for each value in the list. Any additional arguments passed to the call will be redirected to the method call.
or, in the version of lodash _.invoke(collection, path, [args])
Calls a method along the path for each item in the collection, returning an array of the results of each called method. Any additional arguments are provided for each method invoked. If methodName is a function, it is called for this element and is associated with this every element in the collection.
This way you execute each observable and get its value as expected:
_.invoke(myArray(), "id")
Pay attention to models with full observables!
The first comment on this question made me turn on this notification:
The best solution is to use ko.toJS to convert all observables into a view model into a regular JavaScript object with regular properties. Once you do this, an underscore or any other library will work as expected.
The _.invoke solution _.invoke works for one level observable, like this case. If there were several levels of nested observables, it would completely fail, because it calls a function at the end of the path, and not at every step of the path, for example, _.invoke will not work for this case:
var advices = [{ person: ko.observable({ name = ko.observable('John') }), advice: ko.observable('Beware of the observables!') }];
In this case, you can only use _.invoke in the first level, for example:
var sentences = _.invoke(advices,'advice');
But this did not work:
var names = _.invoke(advices,'person.name');
In this call, only name will be called, but person not, therefore it will not work because person is observable, therefore it does not have a name property.
NOTE: lodash is another library, similar and mostly compatible with underscores, but better in some aspects.