Fork me on GitHub

API Documentation

Top-level (chainable) functions Final functions Other
filter (alias: filtering) get then
index (alias: indexing) set catch
unsafeIndex (alias: unsafelyIndexing) map mixin
slice (alias: slicing)   setter
path (alias: following)   getter
pluck (alias: plucking)   and
recursivePluck (alias: recursivelyPlucking)   or
each    
own    
setting    
mapping    
unsafePath . .

filter

Focus on elements of an array filtered by a regular expression or function.

                nanoscope([1, 2, 3]).filter(function (elem) {
    return (elem % 2 === 0);
}).set(100);

nanoscope(['a', 'B', 'C']).filter(/[a-z]/).get();
            
                 [1, 100, 3]
 ['a']
            

index

Focus on the element of an array at a given index. Returns undefined if the index is out of bounds.

                nanoscope([1, 2, 3]).index(0).map(function (num) {
    return (num + 100);
});
            
                 [101, 2, 3]
            

unsafeIndex

Same as index, but throws errors if trying to access an element outside of array bounds. Allows setting the element directly after the end of an array (arr[arr.length]).

                nanoscope([1, 2, 3]).unsafeIndex(0).get();

nanoscope([]).unsafeIndex(0).get();
            
                 1
 Error: Attempt to access invalid index 0
            

slice

Focus on a slice of an array. A slice can be specified using either start and end bounds (negative bounds count from the end of an array) or by a string in python-style syntax (i.e '1:10').

                nanoscope([1, 2, 3]).slice('1:').get();

nanoscope([1, 2, 3]).slice(0, -1).set([5, 4]);
            
                 [2, 3]
 [5, 4, 3]
            

path

Focus on the value located at some path in an object. Paths are given by .-separated strings. If the value at a path doesn't exist (i.e. accessing {}.a.b), get() will return undefined, even if it would otherwise throw an error. set() will set the value, adding properties as necessary. map() will do the same, but if its output returns undefined, the structure will be unmodified. Note that setting values that don't exist can overwrite parent objects (see the final example).

                var obj = {
    a: {
        b: 'flintstones'
    }
}, lens = nanoscope(obj);

nanoscope.path('a.b').get();

nanoscope.path('a.b.c.d').get();

nanoscope.path('a.b.c.d').set('vitamins');
            
                 'flintstones'
 undefined
 { a: { b: { c: { d: 'vitamins' } } } }
            

unsafePath

The same as path, but does not attempt to catch errors and will instead throw them.

                nanoscope({}).unsafePath('a.b').get();
            
                 Error: Cannot read property 'b' of undefined
            

pluck

Focus on a set of properties in an object matching one of: * an array of properties (e.g. ['a', 'b']), * a regular expression (e.g /[a-b]/) * or a function (e.g function (prop) { return prop.match(/[a-b]/); } Note that this does not recurse into subobjects, and only operates on the top-level properties.

                var lens = nanoscope({
    'abc' : 1,
    'def' : 2,
    'WAT' : null
});

lens.pluck(['abc']).get();

lens.pluck(/[a-d]*/).get();

lens.pluck(function (prop, val) {
    return !val;
}).set('unknown');
            
                 { 'abc': 1 }
 { 'abc': 1, 'def': 2 }
 { 'abc': 1, 'def': 2, 'WAT': 'unknown' }
            

recursivePluck

The same as pluck, but recurses into subobjects.

                var lens = nanoscope({
    a: { b: 100, C: 99 }
});

lens.pluck(/[a-z]/).get();
            
                 { a: { b: 100 } }
            

each

Focus on every element of an array and further process it.

                nanoscope({
    locations: [{x: 100, y: 200}, {x: 10, y: 0}]
}).path('locations')
  .each(function (loc) {
      return loc.path('x');
  }).get();
            
                 [100, 10]
            

own

Focus on every value of an object and further process it.

                nanoscope({
    x: [100],
    y: [200]
}).own(function (val) {
    return val.index(0);
}).get();
            
                 [100, 10]
            

setting

Set the focus of a lens to a new value and return a new lens focusing on the modified object.

                var coordinate = { x: 2, y: 4 };

coordinate.path('x').setting(200).get();
            
                 200
            

mapping

Map a function over the focus of a lens to a new value and return a new lens focusing on the modified object.

                var coordinate = { x: 2, y: 4 },
    square = function (val) { return val * val; };

coordinate.path('y').mapping(square).get();
            
                 16
            

get

Get the value at the focus of the lens and return it.

                var lens = nanoscope([1, 2, 3]).index(2);

lens.get();
            
                 3
            

set

Set the value at the focus of the lens and return a modified structure.

                var lens = nanoscope.index([1, 2, 3]).index(2);

lens.set(100);
            
                 [1, 2, 100]
            

map

Map the value at the focus of the lens to something else using a function and return a modified structure.

                var lens = nanoscope.index([1, 2, 3]).index(2);

lens.map(function (num) {
    return (num * num);
});
            
                 [1, 2, 9]
            

then

Alias for the current lens that (kind of) improves readability.

                nanoscope([{ a: { b: 10 } }]).index(0).then.path('a.b').get();
            
                 10
            

catch

Catch any exceptions thrown from an unsafe lens and handle them with an error handler

                var lens = nanoscope([]).unsafeIndex(10000).catch(console.log);

lens.get();
            
                 [Error: Attempt to access invalid index 10000]
            

mixin

Add a function to `nanoscope`. The `this` context in the lens passed in will be replaced with the current nanoscope context when it is called. Any function like this should return a new Lens (i.e. use only the existing chainable nanoscope functions) or terminate with one of the final functions.

                var within = function (target, alpha) {
    return this.filtering(function (elem) {
        return (target - alpha) < elem  && elem < (target + alpha);
    });
};

nanoscope.mixin({within: within});

nanoscope([10, 2.5, 3]).within(3.5, 1.5).get();
            
                 [2.5, 3.5]
            

setter

Disallow get in a Lens. Typically called at the end of Lens construction because internal functions rely on get occasionally.

                var lens = nanoscope({ a: 100 }).path('a').setter();

lens.set(30);

lens.get();
            
                 { a: 30 }
 Error: get not permitted in a Setter
            

getter

Disallow set and map in a Lens. Typically called at the end of Lens construction because internal functions rely on set and map occasionally.

                var lens = nanoscope([1]).index(0).getter();

lens.get();

lens.set(100);
            
                 1
 Error: map not permitted in a Getter
            

and

Add a view to a lens and focus on both of their foci if and only if both exist.

                var foobar = {foo: 1, bar: 2},
    lens = nanoscope(foobar),
    conjunctiveLens = lens.path('foo').and(lens.path('bar'));

conjunctiveLens.get();

conjunctiveLens = lens.path('foo').and(lens.path('baz'));

conjunctiveLens.get();
            
                 [1, 2]
 null
            

or

Add a view to a lens and focus on the first one that exists.

                var foobar = {foo: 1, bar: 2},
    lens = nanoscope(foobar),
    conjunctiveLens = lens.path('foo').or(lens.path('bar'));

conjunctiveLens.get();

conjunctiveLens = lens.path('baz').or(lens.path('bar'));

conjunctiveLens.get();
            
                 1
 2