Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug or user error? Copying observable to other position in array converts it to the raw item #49

Open
kwaclaw opened this issue Sep 3, 2020 · 0 comments

Comments

@kwaclaw
Copy link

kwaclaw commented Sep 3, 2020

In this code, "this.items" is an observable array, that contains items that are observables themselves.
When I run this code:

 moveItem(from, to) {
    if (from === to) return;

    // this algorithm keeps the array length constant
    const itemToMove = this.items[from];
    if (to > from) {
      this.items.copyWithin(from, from + 1, to + 1);
    } else if (to < from) {
      this.items.copyWithin(to + 1, to, from);
    }
    this.items[to] = itemToMove;
  }

then all the items that are affected by the copy operations, that is, items affected by copyWithin() and also items affected by plain assignments, like in this.items[to] = itemToMove where itemToMove is a proxy, get replaced by their raw items inside the array. So what started oput as an array of proxies ends up as a mixed array of proxies and raw items.

I found one workaround by operating on the raw array first, but it is not elegant:

moveItem(from, to) {
    if (from === to) return;

    const items = raw(this.items);

    // this algorithm keeps the array length constant
    const itemToMove = items[from];
    if (to > from) {
      items.copyWithin(from, from + 1, to + 1);
    } else if (to < from) {
      items.copyWithin(to + 1, to, from);
    }
    items[to] = itemToMove;

    // we made changes on the raw array, because copyWithin and assignments applied to the proxy
    // 'this.items' strip the copied/assigned array elements of any proxies that might wrap them.
    // So we need to trigger a reaction explicity on this.items by clearing and re-assigning to it.
    this.items = [];
    this.items = items;
  }

Am I missing something? Is there a better way to do this?

@kwaclaw kwaclaw changed the title Observable array of observable items replaces proxies with raw items Copying observable to other position in array converts it to the raw item Oct 4, 2020
@kwaclaw kwaclaw changed the title Copying observable to other position in array converts it to the raw item Bug or user error? Copying observable to other position in array converts it to the raw item Oct 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant