Skip to content

An Observable Array for javascript in ES6 (ES2015) modules

License

Notifications You must be signed in to change notification settings

the1076/loud-array

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LoudArray

An Observable Array for javascript in ES6 (ES2015) modules

Description

LoudArray is a library used for observing arrays written in vanilla Javascript using a suite of ES6 functionality. The entire library is <5kB expanded and <3kB minified. This code has been prioritized for readability and, as such, may benefit greatly from optimization.

Why "Loud"? Because this is an array you can listen to. Not only can you listen to it, but you can add as many listeners (and, therefore, handlers) as you'd like. Everything this array does can be heard because this array is LOUD!

Demo

A live demo can be viewed on Codepen and a single-page version of the demo is included in this repo as "test.html".

Getting Started

Importing the library

LoudArray is a standard ES6 module so it can be imported in the common ways:

import LoudArray, { ArrayListener, ArrayEvent } from "./loud-array.js";

or (for the minified version)

import LoudArray, { ArrayListener, ArrayEvent } from "./loud-array.min.js";

Usage

Initialization

To start working with an observable array, create a new instance of LoudArray:

let myLoudArray = new LoudArray();

You can use an instance of a LoudArray just like you would any other array object. If you don't add any listeners, LoudArray should function exactly like any other array.

If you would like to include listeners during instantiation (rather than adding them later), simply include an array of key-value pairs that have event and handler properties:

let myLoudArray = new LoudArray([{event: 'after-all', handler: (array, args) => { console.log(array); }]);

If you have imported the ArrayListener class, you can use instances of that object to define your listeners, as well:

let myLoudArray = new LoudArray([new ArrayListener('after-all', (array, args) => { console.log(array); })]);

The first parameter of the LoudArray object is for the listeners, but the functionality to instantiate an array with values has been retained via any additional parameters:

let myListenerArray =
[
    new ArrayListener('after-all', (array, args) => { console.log(array); })
];
let sourceArray = ["these", "are", "some", "initial", "values"];
let myLoudArray = new LoudArray(myListenerArray, "start value 1", "start value 2");
//or
let myLoudArray = new LoudArray(myListenerArray, ...sourceArray);
//or
let myLoudArray = new LoudArray(null, "start value 1", "start value 2", ...sourceArray);

Listeners

The LoudArray object only introduces two new methods to the standard methods of an Array. These two methods allow you to add and remove listeners just like you would with an HTMLElement object. Unlike the HTMLElement objects, however, you can pass in a single parameter that is an instance of an ArrayListener object, instead, to either of these functions.

  • addEventListener()
    SyntaxaddEventListener(eventType, handler) or addEventListener(arrayListener)
    Descriptionadds a listener to the LoudArray instance.
    Params Name Type Description
    eventType string A string value representing when the event should be dispatched.
    Examples: "after-push", "before-splice", "before-all".
    (The helper class ArrayEvent contains all valid eventType values.)
    handler function The function that will be executed when the target event occurs.
    Returns ArrayListener The ArrayListener object that was added to the array.
  • removeEventListener()
    SyntaxremoveEventListener(eventType, handler) or removeEventListener(arrayListener)
    Descriptionremoves a listener from the LoudArray instance.
    ParamsNameTypeDescription
    eventTypestringThe eventType of the ArrayListener that is to be removed from the LoudArray instance.
    (The helper class ArrayEvent contains all valid eventType values.)
    handlerfunctionThe exact function that was used as a handler on the ArrayListener instance to be removed.
    Returnsundefined

Handler Arguments

When LoudArray executes a handler it forgoes the traditional event object and, instead, provides the current state of the array as the first argument, and then any values that were passed to the mutation function being used as the second argument. An example handler might look like:

function myLoudArray_afterFill(array, methodArgs)
{
  console.log(array); //current state of the array
  console.log(methodArgs); //an array of the arguments passed to the "fill" method.
}

let myLoudArray = new LoudArray(null, [0,1,2,3,4]);
myLoudArray.addEventListner('after-fill', myLoudArray_afterFill);

myLoudArray.fill("all elements will have this value", 0, 5);

The above code would generate the following console logs:

["all elements will have this value", "all elements will have this value", "all elements will have this value", "all elements will have this value", "all elements will have this value"]
["all elements will have this value", 0, 5]

The first log being the newly modified array and the second log being the parameters that were passed in to the fill method.

Array Functionality

The LoudArray object is a child object that extends the native Array object and, as such, retains all of its properties and methods. The only methods that have been changed in the LoudArray object are those methods that directly manipulate the contents of an array. Any functionality that you can perform on an Array should also be able to be performed on a LoudArray, including referencing all of its accessors and methods in the standard ways. Properties like length and indexes should work exactly as you would expect them to on an Array instance.

For examples, all of the following snippets work:

let test = myLoudArray[2]; //sets the 'test' variable to the third item in the LoudArray.
let myLoudArray = new LoudArray(null, ["one", "two", "three"]);
let test = myLoudArray.length; //sets the 'test' variable to the length of the LoudArray (3);
let newArray = myLoudArray.slice(0, 5); //sets the 'newArray' variable to the first five elements of the myLoudArray instance.
//Note that the newArray variable will be a simple array, rather than a LoudArray instance. This is also true of the concat() method.

Helpers

To facilitate type safety (as little of that is possible in vanilla JS...) and ease of use, the LoudArray library comes with two helper classes.

The ArrayListener class is a simple object storing two properties: the event and the handler. These correlate to the two parameters required to add an event listener to a LoudArray instance.

The ArrayEvent class is an enumerator (in a rough sense. Because, again, vanilla JS...) that holds static values of all acceptable event types that can be passed in to either the addEventListener() or removeEventListener() methods on a LoudArray instance, or in to the constructor of an ArrayListener instance.

ArrayListener

Usage

An ArrayListener instance requires two values to be passed in to its constructor that define the event type to listen for, and the handler function to execute, respectively. In example:

let myListener = new ArrayListener('before-slice', () => { console.log('slicing, but no diceing. =('); });
let myAfterListener = new ArrayListener(ArrayEvent.AfterSlice, () => { console.log("That's some sliced fruit, dawg"); });
let fruits = new LoudArray([myListener, myAfterListener], ['mango', 'passionfruit', 'strawberry', 'tomato', 'tangelo']); //obviously, in a real-world scenario, this would throw an error as a tomato is not a culinary fruit.

Properties

Name Type Description
event string A string value representing when the event should be dispatched.
Examples: "after-push", "before-splice", "before-all".
(The helper class ArrayEvent contains all valid eventType values.)
handler function The function that will be executed when the target event occurs.

Methods

constructor()
SyntaxArrayListener(event, handler)
Descriptioncreates a new ArrayListener instance
ParamsNameTypeDescription
eventstringA string value representing when the event should be dispatched.
Examples: "after-push", "before-splice", "before-all".
(The helper class ArrayEvent contains all valid eventType values.)
handlerfunctionThe function that will be executed when the target event occurs.
ReturnsArrayListener

ArrayEvent

Usage

The ArrayEvent class is a static class used as a string enumerator. It cannot be instantiated and contains no methods. It is only meant as a way to enumerate the possible event types and, therefore, facilitate developers who are unfamiliar with those values.

let myListener = new ArrayListener(ArrayEvent.AfterAll, () => { console.log('these years, you are still the one I want whispering in my ear'); });
let myAfterListener = new ArrayListener(ArrayEvent.BeforePush, () => { console.log("you around, well I will, well I will. If I wanna push you down, well I will, well I will"); });
let fruits = new LoudArray([myListener, myAfterListener]);

Properties

Name Type Description
BeforeAll string "before-all"
BeforeCopyWithin string "before-copy-within"
BeforeFill string "before-fill"
BeforePop string "before-pop"
BeforePush string "before-push"
BeforeReverse string "before-reverse"
BeforeShift string "before-shift"
BeforeSort string "before-sort"
BeforeSplice string "before-splice"
BeforeUnshift string "before-unshift"
AfterAll string "after-all"
AfterCopyWithin string "after-copy-within"
AfterFill string "after-fill"
AfterPop string "after-pop"
AfterPush string "after-push"
AfterReverse string "after-reverse"
AfterShift string "after-shift"
AfterSort string "after-sort"
AfterSplice string "after-splice"
AfterUnshift string "after-unshift"

Methods

None

Compatability

Tested and working in modern versions of the following browsers:

  • Chrome
  • Firefox
  • Edge

Notes

  • The ArrayEvent helper class is strictly used for developer-friendliness and could be removed with no additional code changes, if it is not relied upon.
  • The ArrayListener helper class is used for known-objects and properties, so it is a little more integrated but could also be removed, with minor rework.

FAQ

Where is LoudArray on NPM?

LoudArray has not been published on NPM. Mainly because I've never published anything on NPM and don't know how to format this code to work with Node. If someone wants to walk me through it, I'm all ears. Until then, there are no specific plans to publish LoudArray on NPM.

loud-array.micro

LoudArray was developed to serve a wide variety of purposes but I hate to ship a library with features that most people won't use. I tried to keep LoudArray fairly svelte but there's plenty of fat to be trimmed. To that end, I've pared down the LoudArray library to make an even smaller library that can serve use cases that don't require as much versatility. The micro version of the library clocks in at ~3kB expanded and just under 2kB minified.

The major changes are:

  • Removed the "before" event ability, thereby negating the need to handle events as "after". Instead, there is a single callback to be passed in, just like with the addEventListener() function that exists on HTMLElement objects. This callback will always occur after a change to the array has been made.
  • The eventType parameter for the addEventListener() consists only of the method name (in dash-delimited lowercase), without a "before" or "after" prefix. In example: This LoudArray code:
    myObservableArray.addEventListener('before-copy-within', (array, args) => { console.log('test'); } );
    
    would be written with loud-array.micro as:
    myObservableArray.addEventListener('copy-within', (array, args) => { console.log('test'); } );
    
  • Removed both ArrayListener and ArrayEvent helper classes.