Skip to content

SArray.slice() versus slicing the update value #75

Open
@asprionj

Description

I'm currently playing around with S/Surplus because I really like its approach / philosophy. I have a keyed list implemented as Map. I want to show the entries of this map filtered and in a specific order. My idea is to use an SArray containing all keys to render the relevant entries only and in the desired order. In addition, I only want to show a reduced number of entries, but that can be extended by the user. Here's an (almost) minimal example:

import * as Surplus from 'surplus';
import SArray from 's-array';
import data from 'surplus-mixin-data';
import S from 's-js'

var content = new Map([[0,"a"], [1,"b"], [2,"c"], [3,"d"]]);

// initial view: reversely-ordered list, max. 3 entries shown
const showInds = SArray(Array.from(content.keys()).reverse());
var tableLength = S.data(3);

// function to sort the list (alphabetically)
const sortList = () => {
  let newInds = Array.from(content).sort().map(c => c[0]);
  showInds(newInds.slice(0,tableLength())); // <-- limiting number of entries here
}

const view =
  <div>
    <div>
      {showInds.map(key => // <-- mapping over the entire SArray
          <div onClick={ev => deleteOne(key)}>{content.get(key)}</div>)}
    </div>
    <button onclick={(ev) => sortList()}>sort</button>
    <input type="number" min="0" step="1" fn={data(tableLength)}/>
  </div>

document.body.appendChild(view);

That works fine, but a changed number-of-entries setting only takes effect when sorting the list again. So I thought to slice the SArray itself right before mapping over it in the view, i.e. in the sortList function, just use showInds(newInds); and, in the view, use

showInds.slice(0,tableLength()).map(...

This works fine before hitting the sort button. Once sorted, changing the number of entries to be shown (up or down) results in the runtime error

image
In main.js, that's on the last line of this code snippet:

    function reconcileArrays(parent, ns, us) {
        var ulen = us.length, 
        // n = nodes, u = updates
        // ranges defined by min and max indices
        nmin = 0, nmax = ns.length - 1, umin = 0, umax = ulen - 1, 
        // start nodes of ranges
        n = ns[nmin], u = us[umin], 
        // end nodes of ranges
        nx = ns[nmax], ux = us[umax], 
        // node, if any, just after ux, used for doing .insertBefore() to put nodes at end
        ul = nx.nextSibling, i, j, k, loop = true;

Could very well be that I'm trying to do something in a way it's not meant to be done? However, I was surprised that the two seemingly equivalent solutions don't work the same. Is this a fundamental limitation of the core idea or a bug / missing feature?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions